저는 Linux (셸)를 처음 사용합니다. Linux 셸 스크립트를 사용하여 xml 파일의 base64 텍스트를 디코딩해야 합니다. 인코딩="base64" 속성을 사용하여 해당 태그의 값을 디코딩하는 Linux 쉘 스크립트를 작성하는 데 도움을 줄 수 있습니까? 내 파일 구조는 다음과 같습니다.
<directory-entries>
<entry dn="ads">
<attr name="memberof">
<value>CN=VPN-employee</value>
<value encoding="base64">aGVsbG8gd29ybGQ= </value>
<value encoding="base64">
Q049RmxvcHB5IC0g0LTQvtGB0YLRg9C/INC30LDQutGA0YvRgixPVT1EZXZpY2UgQ29udHJv
bCxPVT1Hcm91cHMsT1U90JHQkNCd0JosREM9aHEsREM9YmM=
</value>
<value encoding="base64">
Q049VVNCLdC00LjRgdC60LggLSDRgtC+0LvRjNC60L4g0YfRgtC10L3QuNC1LE9VPURldmlj
ZSBDb250cm9sLE9VPUdyb3VwcyxPVT3QkdCQ0J3QmixEQz1ocSxEQz1iYw==
</value>
</attr>
</entry>
</directory-entries>
원하는 출력은
<directory-entries>
<entry dn="ads">
<attr name="memberof">
<value>CN=VPN-employee</value>
<value encoding="base64">Hello world </value>
<value encoding="base64"> decoded </value>
<value encoding="base64"> decoded </value>
</attr>
</entry>
</directory-entries>
Active Directory에서 XML을 생성하기 위해 ldapsearch를 사용하고 있습니다. 파일을 가져오는 데 사용하는 스크립트는 다음과 같습니다.
ldapsearch -h host -p 389 -D "CN=informatica,OU=Accounts for System Purposes,OU=System Accounts,DC=hq,DC=bc" -w password -s sub -B -E UTF-8 -X "(&(objectClass=organizationalPerson)(CN=*))" employeeID memberof > ldap_logins.xml
xml 파일을 생성하는 동안 텍스트를 디코딩하는 것이 가능한지 모르겠습니다. 미리 감사드립니다!
답변1
제가 평소에 무엇을 하는지 이야기해보겠습니다. XML을 구문 분석하는 데 정규식을 사용하지 마십시오. 이것은 나쁜 소식입니다. XML은 다양한 형식으로 제공됩니다. 이는 의미상 동일한 XML이 특정 정규식과 일치하거나 일치하지 않음을 의미합니다. 줄 바꿈, 단항 태그 등과 같은 간단한 것입니다.
이는 업스트림 데이터 흐름의 완벽하게 유효한 변경으로 인해 어느 날 알 수 없는 이유로 깨질 수 있는 취약한 코드를 생성한다는 의미입니다.
파싱을 위해당신의XML 사용을 권장 perl
하며 꽤 좋습니다.XML::Twig
기준 치수.
#!/usr/bin/perl
use strict;
use warnings;
use XML::Twig;
use MIME::Base64;
#we take a "value" element, check it for an "encoding=base64" and if it is
#we rewrite the content and delete that attribute in the XML.
sub decode_value {
my ( $twig, $value ) = @_;
if ( $value->att('encoding')
and $value->att('encoding') eq "base64" )
{
my $decoded_text = decode_base64( $value->text );
if ( $decoded_text =~ m/[^\s\d\w\=\-\,\.]/ ) {
$decoded_text = "decoded";
}
$value->set_text($decoded_text);
$value -> del_att('encoding');
}
}
#twig handlers 'fires' a piece of code each time you hit a 'value' element.
#it passes this piece of code that chunk of XML to handle, which means
#you can do things like dynamic XML rewrites
#pretty print controls output XML rendering - there's a variety of options
#check the manpage.
my $twig = XML::Twig->new(
pretty_print => "indented",
twig_handlers => { 'value' => \&decode_value, }
);
$twig->parsefile('your_xml_file');
$twig->print;
그러면 다음이 제공됩니다.
<directory-entries>
<entry dn="ads">
<attr name="memberof">
<value>CN=VPN-employee</value>
<value encoding="base64">hello world</value>
<value encoding="base64">decoded</value>
<value encoding="base64">decoded</value>
</attr>
</entry>
</directory-entries>
다음과 같이 변환 할 수도 있습니다 $decoded_text
.
$decoded_text =~ s/[^\s\d\w=,-. ]+/_/g;
( URI::Escape
여기에 있는 모듈은 텍스트 URL 스타일을 "퍼센트 인코딩"하므로 살펴볼 가치가 있습니다.)
그러면 다음이 제공됩니다.
<value encoding="base64">CN=Floppy - _ _,OU=Device Control,OU=Groups,OU=_,DC=hq,DC=bc</value>
<value encoding="base64">CN=USB-_ - _ _,OU=Device Control,OU=Groups,OU=_,DC=hq,DC=bc</value>
Net::LDAP
그러나 용도를 사용하면 요구 사항이 충족될 수도 있습니다 .
#!/usr/bin/perl
use strict;
use warnings;
use Net::LDAP;
my $ldap = Net::LDAP->new('host');
my $result = $ldap->bind(
'CN=informatica,OU=Accounts for System Purposes,OU=System Accounts,DC=hq,DC=bc',
'password'
);
if ( $result->code ) { die "Error connecting to LDAP server"; }
my $ldap_search = $ldap->search(
base => 'DC=hq,DC=bc',
scope => 'subtree',
filter => '(&(objectClass=organizationalPerson)(CN=*))',
attrs => [ 'employeeID', 'memberOf' ],
);
foreach my $entry ( $ldap_search->entries ) {
print "dn:\t", $entry->dn(), "\n";
foreach my $attr ( $entry->attributes ) {
print "$attr:";
foreach my $value ( $entry->get_value($attr) ) {
next unless defined $value;
if ( $value =~ m/[^\s\d\w,-=+@\'.()]/ ) { $value = "binary_data" }
chomp($value);
print "\t$value\n";
}
}
}
답변2
컴팩트 스크립트
xml이 에 있다고 가정하고 file.xml
다음을 수행하십시오.
sed -r 's/("base64">)([[:graph:]]+)/\1'"`grep -oP '"base64">\K[[:graph:]]+' file.xml | base64 -d`"'/g' file.xml
다음은 작업을 수행하는 간단한 정규식입니다. 분해해서 설명하겠습니다.
무너지다
먼저 grep을 사용하여 Base64 문자열을 선택하고 디코딩합니다.
grep -oP '"base64">\K[[:graph:]]+' file.xml | base64 -d
변수에 저장할 수 있습니다.
baseString=`grep -oP '"base64">\K[[:graph:]]+' file.xml | base64 -d`
그런 다음 sed
base64를 변수에 저장된 디코딩된 문자열로 바꿉니다.
sed -r 's/("base64">)([[:graph:]]+)/\1'"$baseString"'/g' file.xml
답변3
를 사용하는 것이 정답입니다 xmlstarlet
. 이것은 XML 구문 분석 및 편집을 위한 도구입니다. 먼저 이 패키지를 시스템에 설치하십시오. Debian 기반 시스템을 사용하는 경우 다음을 수행하십시오.
sudo apt-get install xmlstarlet
지금,
- 먼저 base64로 인코딩된 문자열의 값을 읽습니다.
- 그런 다음 이 문자열을 디코딩합니다.
- 그런 다음 해당 태그 값을 수정합니다.
전체 스크립트는 다음과 같습니다.
#!/bin/bash
for i in $(seq 3)
do
#Find the string and decoded it and save it in a variable
decodedString=`xmlstarlet sel -t -v "/directory-entries/entry/attr/value[@encoding='base64'][$i]" file.xml | tr -d \r\n[:space:] | base64 -d`
#Now modify the xml document
xmlstarlet ed -L -u "/directory-entries/entry/attr/value[@encoding='base64'][$i]" -v "$decodedString" file.xml
done
나는 이것을 3 루프 동안 수행했습니다. 원하는 수의 요소로 이 작업을 수행할 수 있습니다.
답변4
xq
다음에서 사용https://kislyuk.github.io/yq/:
xq -x '( .. | select(type == "object" and ."@encoding" == "base64")."#text" )
|= ( gsub("\n"; "") | @base64d )' file.xml
이는 전체 문서를 재귀적으로 탐색하여 encoding
값이 base64
.인 속성을 가진 노드를 찾습니다. 이러한 각 노드에 대해 노드의 값을 가져오고 모든 줄바꿈을 제거하고( 사용 gsub()
) 연산자를 사용하여 base64 문자열을 디코딩합니다 @base64d
. 디코딩된 값은 원래 Base64 데이터를 대체합니다.
문제의 문서가 주어지면 출력은 다음과 같습니다.
<directory-entries>
<entry dn="ads">
<attr name="memberof">
<value>CN=VPN-employee</value>
<value encoding="base64">hello world</value>
<value encoding="base64">CN=Floppy - доступ закрыт,OU=Device Control,OU=Groups,OU=БАНК,DC=hq,DC=bc</value>
<value encoding="base64">CN=USB-диски - только чтение,OU=Device Control,OU=Groups,OU=БАНК,DC=hq,DC=bc</value>
</attr>
</entry>
</directory-entries>
이 도구 에는 "내부" 편집을 수행 할 수 있는 xq
옵션도 있습니다 .-i
--in-place