สงครามอุโมงค์: การเปิดเผยแคมเปญ DNS Tunneling โดยใช้โมเดลทั่วไป – กรณีศึกษา CoinLoader - การวิจัยจุดตรวจสอบ (2023)

การแนะนำ

หากพูดอย่างเคร่งครัด Geneative AI มีมาเกือบทศวรรษแล้ว แต่ความเจริญอย่างรวดเร็วของเทคโนโลยีนี้ได้สร้างแรงบันดาลใจให้เกิดความสนใจใหม่ในแอปพลิเคชันที่เป็นไปได้เพื่อเผชิญกับความท้าทายที่ชุมชนความปลอดภัยของข้อมูลต้องเผชิญ การค้นหาความท้าทายเหล่านี้ต้องอาศัยการค้นหาในกองหญ้าขนาดใหญ่ที่ประกอบด้วยไบนารี เอกสาร โดเมน และสิ่งประดิษฐ์อื่นๆ ที่เกิดขึ้นใหม่บนเว็บทุกวัน

ในบล็อกโพสต์นี้ เราให้ข้อมูลเจาะลึกเกี่ยวกับการใช้งานโมเดลดังกล่าวอย่างต่อเนื่องของ Check Point เพื่อกวาดล้างกองหญ้านี้ และขัดขวางแคมเปญที่เป็นอันตรายซึ่งใช้โปรโตคอล DNS ในทางที่ผิดเพื่อสื่อสารกับเซิร์ฟเวอร์ C&C เป็นประจำ เรามุ่งเน้นไปที่แคมเปญหนึ่งของ CoinLoader และจัดวางโครงสร้างพื้นฐานตลอดจนการวิเคราะห์เชิงลึกทางเทคนิคของฟังก์ชัน DNS tunneling

หลักสูตรข้อขัดข้องใน DNS Tunneling

DNS คืออะไร?

โปรโตคอลเซิร์ฟเวอร์ชื่อโดเมน (DNS) ถือได้ว่าเป็น “สมุดโทรศัพท์ของอินเทอร์เน็ต” เมื่อคุณป้อนที่อยู่เว็บไซต์ (เช่นวิกิพีเดีย.org) ลงในแถบที่อยู่ของเว็บเบราว์เซอร์ของคุณแล้วกด Enter เว็บเบราว์เซอร์ของคุณจะส่งคำขอ DNS ไปยังเซิร์ฟเวอร์ DNS ที่ชื่นชอบ โดยถามว่าที่อยู่ IP ใดที่สอดคล้องกับโดเมนนั้น ที่อยู่ IP ของเซิร์ฟเวอร์ DNS เริ่มต้นนี้จัดทำโดยผู้ให้บริการเครือข่ายของผู้ใช้หรือระบุด้วยตนเองโดยผู้ใช้

ภายใต้ประทุน แบบสอบถาม DNS ทั่วไปจะขี่อยู่เหนือโปรโตคอล UDP (เพื่อเขย่าหน่วยความจำของคุณ ในขณะที่ TCP จัดการกับปัญหา “เพื่อนของฉันได้รับข้อความนั้นจริงๆ หรือไม่” โดยใช้ซินทรายอคUDP จัดการกับมันโดยใช้ความคิดและการอธิษฐาน) แพ็กเก็ต DNS ไม่ว่าจะเป็นแบบสอบถามหรือการตอบกลับ ประกอบด้วยส่วนหัวและส่วนหลัก 4 ส่วน:

  • คำถามหรือคำถาม – เช่น “ชื่อโดเมนอะไร? คุณคาดหวังคำตอบแบบไหน?”
  • การตอบสนอง - คำตอบสำหรับคำถาม
  • อำนาจ – ข้อมูลเกี่ยวกับเซิร์ฟเวอร์ที่รับผิดชอบในการติดตามที่อยู่โดเมน
  • เพิ่มเติม – ข้อมูลเบ็ดเตล็ด เช่น ที่อยู่ IP ของเซิร์ฟเวอร์ที่เชื่อถือได้

“อุโมงค์” หนึ่งแห่งใช้ DNS อย่างไร

“DNS Tunneling” คือแนวทางปฏิบัติในการใช้ DNS ในทางที่ผิด โดยใช้เป็นช่องทางการสื่อสารที่ซ่อนอยู่ เช่น ระหว่างมัลแวร์และเซิร์ฟเวอร์ C&C ในสถานการณ์สมมตินี้ ผู้ประสงค์ร้ายจะควบคุมทั้งไคลเอนต์และเซิร์ฟเวอร์ ทำให้พวกเขามีพื้นที่เหลือเฟือมากเกี่ยวกับประเภทของการสืบค้น และตำแหน่งที่จะซ่อนส่วนที่ “เผ็ดร้อน” ของการตอบกลับ

อย่างไรก็ตาม รูปแบบที่นักแสดงเลือกนั้นขึ้นอยู่กับข้อจำกัดของโปรโตคอล DNS เอง ตัวอย่างเช่น:

  • ความยาวคำขอและการตอบกลับมีขอบเขต โดเมนทั้งหมดที่กำลังค้นหาต้องไม่เกิน 255 ไบต์ และความยาวสูงสุดของแพ็กเก็ต DNS คือ 576 ไบต์
  • โปรโตคอล DNS ยืมตัวเพื่อการแคชโดยธรรมชาติ เซิร์ฟเวอร์จดบันทึกการตอบกลับที่ส่งไปเมื่อชั่วโมงที่แล้ว และเมื่อถูกถาม ก็แค่ทำซ้ำการตอบกลับ แทนที่จะไปที่เซิร์ฟเวอร์ที่เชื่อถือได้และจู้จี้ว่า “เฮ้ คำตอบเมื่อชั่วโมงที่แล้วนั้นยังใช้ได้อยู่หรือเปล่า” วิธีนี้เหมาะสำหรับผู้ใช้ DNS ที่ถูกกฎหมาย แต่ไม่เหมาะสำหรับไคลเอนต์ DNS tunneling ซึ่งโดยทั่วไปจะใช้การสืบค้นโดเมนย่อยสมมติจำนวนมาก (af34deb93557.maliciousdomain.xyzจากนั้นในภายหลัง48bd9a577d114.maliciousdomain.xyzและอื่นๆ) เพื่อให้ข้อความค้นหามีความสดใหม่อยู่เสมอ

หากทั้งหมดนี้ฟังดูเป็นทฤษฎีเกินไป มัลแวร์ที่รู้จักกันดีตัวหนึ่งซึ่งใช้ช่องทาง DNS ก็คือแบ็คดอร์ SUNBURST ที่มีชื่อเสียงโด่งดัง ซึ่งถูกส่งไปยังเหยื่อที่ไม่สงสัยโดยเป็นส่วนหนึ่งของเหตุการณ์ที่น่าอับอายในปี 2020แฮ็ค SolarWinds. SUNBURST ใช้การสืบค้น DNS เป็นช่องทาง light recon โดยถ่ายโอนข้อมูลของเหยื่ออย่างซ่อนเร้นซึ่งเข้ารหัสไว้เป็นตัวระบุ จากนั้นใช้เป็นโดเมนย่อยในการสืบค้น DNS โดเมนย่อยนี้ถูกเพิ่มเข้ากับหนึ่งในสี่โดเมนหลัก:

appsync-api.us-east-1[.]avsvmcloud[.]com
appsync-api.us-east-2[.]avsvmcloud[.]com
appsync-api.eu-west-1[.]avsvmcloud[.]com
appsync-api.us-west-2[.]avsvmcloud[.]com

ตัวอย่างเช่น ผลลัพธ์ FQDN ที่สมมติขึ้นจะมีลักษณะดังนี้:
7cbtailjomqle1pjvr2d32i2voe60ce2[.]appsync-api[.]us-east-1[.]avsvmcloud[.]com.
ตามข้อมูลที่ถ่ายโอนผ่านคำขอ DNS เซิร์ฟเวอร์ DNS จะส่งคืนบันทึก CNAME ไปยังเป้าหมายที่สนใจ CNAME จะชี้ไปที่เซิร์ฟเวอร์ C&C ที่สื่อสารกับมัลแวร์ผ่าน HTTPS

การวิเคราะห์อุโมงค์ DNS

ผู้พิทักษ์ที่มุ่งมั่นซึ่งยืนอยู่บนเกตเวย์เครือข่ายสามารถตรวจจับ DNS tunneling ได้หรือไม่ นี่เป็นคำถามที่น่าประหลาดใจ เนื่องจากคำจำกัดความของ DNS tunneling นั้นกว้างมาก และการใช้งานบางอย่างตรวจพบได้ยากกว่าการใช้งานอื่นๆ เราแสดงรายการจุดสนใจบางจุดด้านล่างที่ควรค่าแก่การคำนึงถึงขณะวิเคราะห์กิจกรรมที่สงสัยว่าเป็นอุโมงค์ DNS

เราถามตัวเองด้วยคำถามต่อไปนี้:

  • เท่าไหร่?และนานแค่ไหน?ดูจำนวนและความยาวของโดเมนย่อยที่เกี่ยวข้องกับโดเมนที่น่าสงสัย ดังที่กล่าวไว้ก่อนหน้านี้ แพ็กเก็ต DNS มีขนาดจำกัด ทำให้ผู้ดำเนินการมีช่องข้อมูลจำนวนเล็กน้อยในการจัดการ วิธีที่มีประสิทธิภาพที่สุดในการถ่ายโอนข้อมูลในการสืบค้น DNS คือการใช้โดเมนย่อย ซึ่งส่งผลให้มีคำขอ DNS จำนวนมากไปยังโดเมนย่อยหลายโดเมนซึ่งมักจะยาวในโดเมนเดียวกัน นอกจากนี้ยังช่วยหลีกเลี่ยงปัญหาแคชที่อาจเกิดขึ้นอีกด้วย
สงครามอุโมงค์: การเปิดเผยแคมเปญ DNS Tunneling โดยใช้โมเดลทั่วไป – กรณีศึกษา CoinLoader - การวิจัยจุดตรวจสอบ (1)
  • ใครตอบ?DNS นั้นเชื่อถือได้ ซึ่งหมายความว่าเนมเซิร์ฟเวอร์เฉพาะ (NS) มีหน้าที่รับผิดชอบในการแก้ปัญหาขั้นสุดท้ายของโดเมนที่ระบุ การสืบค้น DNS สำหรับโดเมนเหล่านั้นจะสิ้นสุดการเข้าถึงเซิร์ฟเวอร์เหล่านั้นในที่สุด (เว้นแต่ว่าจะมีการแคชไว้ที่ไหนสักแห่งระหว่างทาง) เพื่ออำนวยความสะดวกในการทันเนล DNS นักแสดงจะต้องควบคุมเนมเซิร์ฟเวอร์ที่เชื่อมโยงกับโดเมนใดโดเมนหนึ่ง การดูบันทึก NS หรือบันทึก WHOIS ของโดเมนที่น่าสงสัย ซึ่งระบุเนมเซิร์ฟเวอร์ที่เชื่อถือได้สำหรับโดเมนนั้น อาจชี้ไปที่โครงสร้างพื้นฐานของผู้แสดงภัยคุกคาม

การตอบคำถามเหล่านั้นอาจไม่ใช่เรื่องง่าย แต่โชคดีสำหรับเราในฐานะนักวิจัย หลายๆ คำถามสามารถตอบได้โดยใช้แหล่งข้อมูลสาธารณะ Passive DNS เป็นเครื่องมือที่มีประโยชน์มากในการคัดแยกภัยคุกคามที่หลากหลาย แต่มีประสิทธิภาพอย่างมากเมื่อต้องจัดการกับ DNS tunneling เนื่องจากการทันเนล DNS อาศัยโปรโตคอล DNS เอง การจำลอง DNS แบบพาสซีฟจึงมักจะสร้างเอกสารที่ถ่ายโอนไปด้วย ในบางกรณีก็อาจเป็นไปได้ด้วยซ้ำดึงข้อมูลที่เกี่ยวข้องกับผู้ที่ตกเป็นเหยื่อตัวพวกเขาเอง.

ขอแนะนำ DeepDNS

จากความสนใจอย่างต่อเนื่องของเราในเรื่องอุโมงค์ DNS โดยทั่วไปและการรับส่งข้อมูลเว็บที่เป็นอันตราย ในปีนี้ เราได้เห็นการเปิดตัว DeepDNS ซึ่งเป็นเครือข่ายประสาทเทียมที่ตามล่าและบล็อกแคมเปญที่ใช้ DNS ในทางที่ผิด DeepDNS คือ Gated Recurrent Unit Autoencoder (GRU-AE) ที่ได้รับการฝึกอบรมเกี่ยวกับการรับส่งข้อมูล DNS จำนวนมหาศาลที่ Check Point เป็นประจำซึ่งเป็นส่วนหนึ่งของการวัดและส่งข้อมูลทางไกล ข้อสรุปของ DeepDNS จะถูกส่งไปยัง Check Point ThreatCloud โดยอัตโนมัติ

เอกสารนี้ไม่ใช่บทความเกี่ยวกับการทำงานภายในของ AI อย่างแน่นอน แต่เรายังคงรู้สึกว่าคุณจะได้รับบริการอย่างดีจากคำอธิบายที่เรียบง่ายมากว่า "ตัวเข้ารหัสอัตโนมัติแบบ Gated Recurrent Unit" คืออะไร อย่างน้อยก็ในรูปแบบกว้างๆ

ประการแรก ตัวเข้ารหัสอัตโนมัติคือโครงข่ายประสาทเทียม ซึ่งหมายความว่ามันเป็นสมองเสมือนจริงที่เริ่มต้นชีวิตด้วยกระดานชนวนที่ว่างเปล่า ในระหว่างระยะการฝึก จะมีการป้อนข้อมูล จากนั้นจะสังเกตผลลัพธ์ และการเปลี่ยนแปลงพารามิเตอร์ของสมองที่จะทำให้ผลลัพธ์เป็นที่ต้องการมากขึ้นจะถูกกำหนดโดยใช้แคลคูลัส จากนั้นจึงนำไปใช้ (นี่เป็นวิธีแฟนซีในการบอกว่าคุณหลับตา) ลองจินตนาการว่าความผิดพลาดของเอาท์พุตตามฟังก์ชันของพารามิเตอร์สมองคือภูเขาแล้วลงจากภูเขาให้เร็วที่สุดเท่าที่จะทำได้จนกว่าจะลงไปต่อไปไม่ได้). กระบวนการนี้จะเกิดขึ้นซ้ำจนกว่าผลลัพธ์จริงของสมองเสมือนจะคล้ายกับผลลัพธ์ที่ต้องการอย่างเพียงพอ หากคำอธิบายทั้งหมดนี้ฟังดูแปลกสำหรับคุณ ให้พิจารณาว่ามันไม่ได้แตกต่างจากสิ่งที่คุณทำเมื่อคุณตะโกนซ้ำๆ ว่า “ไม่!! เลขที่!! ปล่อยมันไว้คนเดียว!!!” เมื่ออายุสามขวบของคุณ

สงครามอุโมงค์: การเปิดเผยแคมเปญ DNS Tunneling โดยใช้โมเดลทั่วไป – กรณีศึกษา CoinLoader - การวิจัยจุดตรวจสอบ (2)

โครงข่ายประสาทเทียมมีความสามารถที่น่าประหลาดใจในการเรียนรู้ฟังก์ชันทุกประเภท (นี่คือคู่พิสูจน์แล้วในทางทฤษฎี). ฟังก์ชันหนึ่งดังกล่าวคือ "แมปข้อความนี้กับการแสดงแบบสั้น (โค้ด) จากนั้นเปลี่ยนโค้ดกลับเป็นข้อความเพื่อให้ข้อความสุดท้ายมีลักษณะคล้ายกับข้อความเริ่มต้นให้มากที่สุดเท่าที่จะเป็นไปได้" โครงข่ายประสาทเทียมที่ได้รับการฝึกฝนให้เรียนรู้ฟังก์ชันประเภทนี้เรียกว่าตัวเข้ารหัสอัตโนมัติ โปรแกรมเข้ารหัสอัตโนมัติสามารถทำหน้าที่เป็นโมเดลกำเนิดได้: รับจุดใหม่ในพื้นที่โค้ดในทางใดทางหนึ่ง (โดยการสุ่มเลือกหรือเพียงแค่ผสมจุดที่ทราบบางจุดเข้าด้วยกัน) และหากโมเดลได้เรียนรู้การแสดงข้อมูลที่ดี การถอดรหัสจุดนี้จะ ส่งผลให้เกิดข้อความนวนิยาย เนื่องจากนี่ไม่ใช่ส่วนหนึ่งของข้อกำหนดของโปรแกรมเข้ารหัสอัตโนมัติในทางเทคนิค เอกสารต่างๆ จึงมีการแบ่งแยกเกี่ยวกับวิธีการที่ถูกต้องในการอ้างถึงโมเดลดังกล่าวว่าเป็นโมเดลเชิงกำเนิด ซึ่งต่างจากโมเดลที่มีความสามารถในการสร้าง (ขอให้สนุกกับการค้นหาของ Google นี้); แต่ "โมเดลที่มีความสามารถในการสร้าง" ไม่เข้ากับชื่อหลักมากนัก ดังนั้นเราจึงอยู่ตรงนี้

สงครามอุโมงค์: การเปิดเผยแคมเปญ DNS Tunneling โดยใช้โมเดลทั่วไป – กรณีศึกษา CoinLoader - การวิจัยจุดตรวจสอบ (3)

อีกกรณีการใช้งานสำหรับตัวเข้ารหัสอัตโนมัติที่เกี่ยวข้องกับที่นี้คือการตรวจจับความผิดปกติ การใช้สัญชาตญาณทางคณิตศาสตร์บางอย่างจะทำให้คุณสรุปได้ว่าอินพุต "ทั่วไป" จะถูกบีบอัดและสร้างใหม่โดยโปรแกรมเข้ารหัสอัตโนมัติซึ่งค่อนข้างจะประสบความสำเร็จ ในขณะที่การบีบอัดและการสร้างอินพุต "ผิดปรกติ" ใหม่มีแนวโน้มที่จะทำให้เกิดข้อผิดพลาดมากกว่า โดยพื้นฐานแล้วด้วยเหตุผลเดียวกับที่ถ้าฉันพูดว่า "สุนัขจิ้งจอกสีน้ำตาลกระโดดข้ามสุนัขขี้เกียจ" จากนั้นห้านาทีต่อมาขอให้คุณพูดประโยคนั้นซ้ำ คุณอาจจะประสบความสำเร็จ แต่ก็ไม่เป็นความจริงสำหรับ "ตุ่นปากเป็ดสีม่วงอันล้ำลึก" ทำให้เสือชีตาห์ที่อุดมสมบูรณ์สับสน”

DeepDNS ทำงานบนหลักการเดียวกันนี้ ด้วยการใช้การตรวจสอบชื่อโดเมนย่อยอย่างละเอียดซึ่งแบ่งย่อยออกเป็นส่วนย่อยๆ โดยใช้กระบวนการเข้ารหัส-ถอดรหัสที่เรียนรู้ที่จะตัดสินคำถามง่ายๆ ที่ว่า “ชุดคำสั่งนี้ดูปกติแค่ไหน” หากการสร้างใหม่ล้มเหลวเพียงพอ DeepDNS จะสรุปว่าคำตอบคือ “ไม่ปกติเพียงพอ” และให้คำตัดสินที่เป็นอันตราย แนวทางนี้มีความสง่างามในความเรียบง่าย หากคุณเพิกเฉยต่อส่วนที่การฝึกโมเดลเกี่ยวข้องกับพื้นผิวลอยที่มีสีสันและอนุพันธ์บางส่วนจำนวนมาก

ที่ปลายอุโมงค์ – ตกปลาและเจาะลึกเข้าไปในอุโมงค์ DNS ของ CoinLoader

หลังจากที่เราได้กล่าวถึงทฤษฎีนี้แล้ว ก็ถึงเวลานำไปปฏิบัติจริง เมื่อทราบว่า DeepDNS ทำงานอย่างไรในระดับกล่องดำ (และแม้แต่การทำงานภายในบางส่วนด้วยเนื้อหาข้างต้น) เป็นเรื่องปกติที่จะถามว่าจะสามารถค้นหาอะไรได้บ้างหากเราค้นหาความผิดปกติจากการตรวจวัดทางไกลที่มีอยู่ของเรา เราทำอย่างนั้นและรัน DeepDNS กับตัวอย่างของเรา ในบรรดาผลลัพธ์มากมายที่ถูกตั้งค่าสถานะว่าผิดปกติ มีกลุ่มโดเมนที่ไม่รู้จักก่อนหน้านี้กลุ่มหนึ่งที่ดึงดูดสายตาของเราเป็นพิเศษ:

  • ข้อมูล rqmetrixsdn[.]
  • ข้อมูล candatamsnsdn[.]
  • ข้อมูลแผนที่ datamsnsdn[.]

เมื่อพิจารณาโครงสร้างพื้นฐานที่เชื่อมต่อกับโดเมนเหล่านี้อย่างละเอียดยิ่งขึ้น บ่งชี้ว่าโดเมนเหล่านี้เป็นส่วนหนึ่งของช่องทางสำรอง DNS ที่ใช้สำหรับการติดเชื้อ CoinLoader

Coinloader ได้รับการอธิบายครั้งแรกในรายงานที่ครอบคลุมนี้โดย Aviraแต่เราไม่พบเอกสารก่อนหน้านี้ที่อธิบายคุณลักษณะเฉพาะนี้ พบตัวอย่างในเอกสารสำคัญ โดยทั่วไปคือราร์หรือกซิปซึ่งมีหลายไฟล์ แม้ว่าชื่อจะแตกต่างกันไป แต่สิ่งที่คุณเห็นด้านล่างนี้เป็นตัวแทนของโครงสร้างไฟล์ในแต่ละตัวอย่างไม่มากก็น้อย

สงครามอุโมงค์: การเปิดเผยแคมเปญ DNS Tunneling โดยใช้โมเดลทั่วไป – กรณีศึกษา CoinLoader - การวิจัยจุดตรวจสอบ (4)

ปฏิบัติการ (ซด_1.4.24.17ในภาพ) เป็นเครื่องมือที่ถูกต้องตามกฎหมายซึ่งใช้สำหรับการโหลด DLL เสมอ ตรรกะที่เป็นอันตรายหลักอยู่ใน DLL ที่ไซด์โหลด (ที่นี่AppleVersions.dll). เมื่อโหลดแล้ว จะผ่านการแกะบรรจุภัณฑ์หลายชั้น รวมถึงการตรวจสอบที่ซับซ้อนว่ากระบวนการหลักถูกเรียกใช้จากภายในZ-1-36-81ไดเร็กทอรี (อีกครั้ง ชื่อไดเร็กทอรีแตกต่างกันไปในแต่ละตัวอย่าง) ซึ่งฝังอยู่ภายในโครงสร้างโฟลว์การควบคุมที่ซับซ้อน

สงครามอุโมงค์: การเปิดเผยแคมเปญ DNS Tunneling โดยใช้โมเดลทั่วไป – กรณีศึกษา CoinLoader - การวิจัยจุดตรวจสอบ (5)

เมื่อการแกะกล่องเสร็จสิ้น ตรรกะที่เป็นอันตรายก็จะปรากฏให้เห็น ขั้นตอนสุดท้ายนี้ยังคงมีคุณสมบัติต่อต้านการวิเคราะห์หลายประการ เช่น รหัสขยะ สตริงสแต็กที่เข้ารหัสซึ่งถอดรหัสได้ทันทีโดยใช้รหัสทดแทนแบบง่าย และการเรียกทางอ้อมที่ได้รับการแก้ไขโดยใช้ตารางฟังก์ชัน homebrew ซึ่งรีจิสเตอร์ชี้ไปที่สิ่งที่ส่งผ่านไปยังแต่ละฟังก์ชันในอีเอ็กซ์. นี้ จากนั้นจะถูกคัดลอกไปยังการลงทะเบียนแบบสุ่มในแต่ละครั้งซึ่งใช้ในการดำเนินการโทร

สงครามอุโมงค์: การเปิดเผยแคมเปญ DNS Tunneling โดยใช้โมเดลทั่วไป – กรณีศึกษา CoinLoader - การวิจัยจุดตรวจสอบ (6)
สงครามอุโมงค์: การเปิดเผยแคมเปญ DNS Tunneling โดยใช้โมเดลทั่วไป – กรณีศึกษา CoinLoader - การวิจัยจุดตรวจสอบ (7)
สงครามอุโมงค์: การเปิดเผยแคมเปญ DNS Tunneling โดยใช้โมเดลทั่วไป – กรณีศึกษา CoinLoader - การวิจัยจุดตรวจสอบ (8)

แม้ว่าโค้ดขยะจะถูกละเว้นได้ดีที่สุด และสตริงที่สับสนจะได้รับการจัดการได้ดีที่สุดโดยการรันโค้ดแบบไดนามิกและสังเกตเอาต์พุตของตัวถอดรหัส ความละเอียดของการเรียกใช้ฟังก์ชันในฐานข้อมูล IDA จำเป็นต้องมีสคริปต์เฉพาะ หากต้องการดูสคริปต์ดังกล่าว ให้ไปที่ภาคผนวก A

การจับปริมาณข้อมูลที่สร้างโดยตัวอย่างหนึ่งดังกล่าวดูเหมือนจะมีแนวโน้มดี:

สงครามอุโมงค์: การเปิดเผยแคมเปญ DNS Tunneling โดยใช้โมเดลทั่วไป – กรณีศึกษา CoinLoader - การวิจัยจุดตรวจสอบ (9)

ดังนั้นเราจึงเริ่มทำการวิเคราะห์ทางเทคนิคของฟีเจอร์นี้
ฟังก์ชั่นget_c2_domainได้รับอาร์กิวเมนต์แจงนับ (ที่นี่ส่งผ่านในการลงทะเบียนเอ็ดเอ็กซ์). ค่า 0, 1, 2 และ 3 ทำให้ฟังก์ชันถอดรหัสและส่งคืนชื่อโดเมน C&C ที่ฮาร์ดโค้ดของมัลแวร์แต่ละตัวตามลำดับ ในกรณีนี้rqmetrixa.info,rqmetrixb.info,rqmetrixc.info,rqmetrixd.info(เรารู้สึกผิดหวังจริงๆ ที่ไม่พบตรรกะบางอย่างที่ต่อท้ายจดหมายถึงrqmetrixแต่สิ่งเหล่านี้ล้วนฮาร์ดโค้ดตามที่เป็นอยู่)

สงครามอุโมงค์: การเปิดเผยแคมเปญ DNS Tunneling โดยใช้โมเดลทั่วไป – กรณีศึกษา CoinLoader - การวิจัยจุดตรวจสอบ (10)

สุดท้ายนี้ หากค่าแจงนับนี้เท่ากับ 4 (ด้านบนมีหมายเหตุประกอบเป็นGET_DOMAIN_DNS_TUNNEL_BACKUP) มัลแวร์หันไปใช้แผนสำรอง และพยายามรับชื่อโดเมนโดยการหารือกับเซิร์ฟเวอร์อื่นrqmetrixsdn.infoผ่านการสืบค้นช่องสัญญาณ TXT DNS ตามที่เห็นในการจับภาพการรับส่งข้อมูล

สงครามอุโมงค์: การเปิดเผยแคมเปญ DNS Tunneling โดยใช้โมเดลทั่วไป – กรณีศึกษา CoinLoader - การวิจัยจุดตรวจสอบ (11)

FQDN ถูกสร้างขึ้นโดยนำหนึ่งในโดเมนฮาร์ดโค้ดมาเติมไว้ข้างหน้าhexlify(md5(ประทับเวลา)). ในภาพด้านล่าง เราแสดงเป็นบล็อกโค้ดเพื่อกรองคำแนะนำที่เป็นขยะออกไป

mov ebx, eaxmov [ebp+md5_of_timestamp], ebxcall [edi+FuncTable.GetSystemTime]xor eax, eax mov [esi+0Eh], axpush ebx ; จัดสรร buffercall mre_get_filetime_md5 ; ตอนนี้มี md5 ของการประทับเวลาปัจจุบัน

ได้รับการประทับเวลา md5 โดยใช้SystemFileToFileTime(จากนั้นแปลงเป็นการประทับเวลาโดยใช้ฟังก์ชัน WinAPI เพิ่มเติม) เมื่อเซิร์ฟเวอร์ตอบสนอง การตอบสนองจะถูกป้อนไปยังตัวถอดรหัส BASE64 แบบอินไลน์ ผลลัพธ์จะถูกตีความว่าเป็นโดเมน C&C ที่ต้องตรวจสอบ คล้ายกับการตั้งค่า SUNBURST ที่เรากล่าวถึงก่อนหน้านี้ รูปแบบการเช็คอินซึ่งเป็นผลลัพธ์ของstring_decoderตัวจัดการการถอดรหัสซอร์สโค้ดที่สร้างความสับสน จะแสดงอยู่ด้านล่าง

สงครามอุโมงค์: การเปิดเผยแคมเปญ DNS Tunneling โดยใช้โมเดลทั่วไป – กรณีศึกษา CoinLoader - การวิจัยจุดตรวจสอบ (12)

บทสรุป

การขุดอุโมงค์ DNS เป็นสิ่งที่คุณอาจเรียกว่าเทคนิค "แบบเก่า" มีต้นกำเนิดมาจากภูมิทัศน์ด้านความปลอดภัยที่สร้างขึ้นโดยการถือกำเนิดของไฟร์วอลล์ชุดแรก และการวาดขอบเขตที่เรียบง่าย: ใครเป็นผู้ริเริ่มการเชื่อมต่อ กับใคร? ที่พอร์ตอะไร? ใช้โปรโตคอลอะไร? ดังนั้นจะอนุญาตหรือปฏิเสธ ตั้งแต่นั้นเป็นต้นมา อุตสาหกรรมก็ได้พัฒนาไปอย่างมาก และประโยชน์ของอุโมงค์ DNS ก็ชัดเจนน้อยลง DNS ไม่ใช่ "ช่องทางแอบแฝง" อีกต่อไปโดยที่ไม่มีโซลูชันด้านความปลอดภัยคิดจะมองเห็นอีกต่อไป และในทางกลับกัน ผู้โจมตีได้ปรับปรุงความเข้าใจเกี่ยวกับวิธีการสื่อสารอย่างมีประสิทธิภาพโดยใช้ HTTP และซ่อนตัวในที่โล่ง โดยใช้เทคนิคที่หลากหลาย เช่น การอำพรางข้อมูลและการเข้ารหัส

ถึงกระนั้น DNS tunneling ก็ยังไม่ตายอย่างชัดเจน ไม่ว่าจะเป็นเพราะมันปรากฏชัดน้อยกว่าในสายตามนุษย์ หรือเพราะผู้เขียนมัลแวร์คิดว่าเทคนิคนี้คุ้มค่าที่จะลองใช้ หากการสื่อสาร HTTP ที่ตรงไปตรงมาล้มเหลว — หรือด้วยเหตุผลอื่น — มัลแวร์สมัยใหม่ไม่อายที่จะมีส่วนร่วมในแนวทางปฏิบัตินี้ ในฐานะกองหลัง เราสนใจที่จะจับมันมาโดยธรรมชาติ ในโพสต์นี้ เราได้อธิบายว่าเป็นไปได้อย่างไรในการสร้างแบบจำลองอุโมงค์ DNS ว่ามีความผิดปกติและค้นหาสิ่งผิดปกติจากมุมมองที่ไม่ธรรมดา ดังที่แสดงด้วย DeepDNS การตามล่าครั้งนี้ได้นำเราไปสู่หลักฐานของนักแสดงจำนวนหนึ่งที่ใช้เทคนิคนี้อยู่ในปัจจุบัน รวมถึงอาชญากรไซเบอร์ที่ได้รับการสนับสนุนจากรัฐและแม้แต่แฮ็กทีวิสต์ ตามตัวอย่าง เราทำการวิเคราะห์ทางเทคนิคของตัวอย่าง Coinlander และโปรโตคอลการขุดอุโมงค์ที่ DeepDNS ตรวจพบว่ามีความผิดปกติ นอกเหนือจากความสนใจโดยธรรมชาติสำหรับเราในฐานะนักล่าภัยคุกคามแล้ว สิ่งนี้ยังทำหน้าที่เป็นข้อพิสูจน์แนวคิดที่ดีสำหรับความสามารถของ DeepDNS อีกด้วย

ในขณะที่นักวิชาการมีไฟฉายในการผลักดันขอบเขตทางวิทยาศาสตร์และพิสูจน์สิ่งที่เป็นไปได้ การนำแนวคิดทางวิชาการไปใช้ในวงกว้างมักตกเป็นหน้าที่ของอุตสาหกรรม และนำทางพวกเขาไปตามเส้นทางจากเอกสารไวท์เปเปอร์ที่มีแนวโน้มดีไปจนถึงการรอดชีวิตจากผลกระทบในโลกแห่งความเป็นจริงที่ยุ่งวุ่นวาย แม้ว่าเราจะทำงานอย่างต่อเนื่องเพื่อนำ ANN มาใช้กับการรักษาความปลอดภัยในระดับวุฒิภาวะดังกล่าว แต่ขอบเขตนี้ยังห่างไกลจากความเหนื่อยล้า ด้วยความสนใจ ANN และแอปพลิเคชันที่เพิ่มขึ้นเมื่อเร็วๆ นี้ เราทำได้เพียงคาดหวังให้สมองประดิษฐ์มีมากขึ้นเรื่อยๆ ในการตัดสินใจด้านความปลอดภัยในโลกแห่งความเป็นจริง และถือเป็นความรับผิดชอบของเราในฐานะอุตสาหกรรมที่พวกเขาทำเช่นนั้นด้วยทักษะและความรับผิดชอบ

ดังนั้น ให้บทความนี้เป็นเครื่องพิสูจน์ถึงช่วงเวลานั้นเมื่อเราพูดว่า "โอ้ โมเดล คุณบอกว่านั่นคือ DNS tunneling เหรอ? ให้นักวิเคราะห์และวิศวกรย้อนกลับของเราตรวจสอบคุณอีกครั้งในเรื่องนี้”

ตัวชี้วัดของการประนีประนอม

ตัวอย่าง CoinLoader

a05144d7254b419d3a09787e280b4be3
84548cf16e26979ff9a3fa2b3f854f34

โครงสร้างพื้นฐาน CoinLoader

ข้อมูล candatamsnsdn[.]
ข้อมูล candatamsna[.]
ข้อมูล candatamsnb[.]
ข้อมูล candatamsnc[.]
ข้อมูล candatamsnd[.]
ข้อมูลแผนที่ datamsnsdn[.]
ข้อมูลแผนที่[.]
ข้อมูลแผนที่ datamsnb[.]
ข้อมูลแผนที่ datamsnc[.]
ข้อมูลแผนที่[.]ข้อมูล
ข้อมูล rqmetrixsdn[.]
ข้อมูล rqmetrixa[.]
ข้อมูล rqmetrixb[.]
ข้อมูล rqmetrixc[.]
ข้อมูล rqmetrixd[.]

ลูกค้าซอฟต์แวร์ Check Point ยังคงได้รับการปกป้องจากภัยคุกคามที่อธิบายไว้ในการวิจัยนี้

จุดตรวจการจำลองภัยคุกคามและจุดสิ้นสุดฮาร์โมนีให้ความคุ้มครองที่ครอบคลุมของกลยุทธ์การโจมตี และป้องกันประเภทของการโจมตีและภัยคุกคามที่อธิบายไว้ในรายงานนี้

จุดสิ้นสุดจุดตรวจสอบฮาร์โมนี:

APT.Win.Coinloader.B
APT.Win.Coinloader.C

การจำลองภัยคุกคามจุดตรวจสอบ:

APT.Wins.Coinloader.A
APT.Wins.Coinloader.D

ภาคผนวก A — สคริปต์ Python สำหรับการแก้ไขฟังก์ชันที่เรียกว่าทางอ้อมในขั้นตอนสุดท้ายของ Coinloader

(ต้องมีตารางฟังก์ชันที่คัดลอกมาจากหน่วยความจำ — ตารางฟังก์ชันตัวอย่างอยู่ด้านล่าง)

จาก abc import ABC, abstractmethod, abstractclassmethod จากการพิมพ์ import List, Tuple, NewType, Dict, Set, Callable, TypeVar, Any, cast, ตัวเลือกจาก functools import wrapsfrom enum import Enumimport sysFuncT = TypeVar("FuncT", bound=Callable[... ,ใดๆ])ลอง: นำเข้า idc #type: ละเว้นการนำเข้า idautils #type: ละเว้นการนำเข้า ida_struct #type: ละเว้นการนำเข้า ida_bytes #type: ละเว้นการนำเข้า ida_idaapi #type: ละเว้นยกเว้น ModuleNotFoundError: ผ่าน #ok ไม่ทำงานภายใน IDA#IDAdef ida( func: FuncT) -> FuncT: ida_modules = set(["idc","idaapi"]) @wraps(func) def wrapper_ida_check(*args: Any, **kwargs: Any) -> Any: ถ้าไม่ได้ตั้งค่า (sys .modules).issuperset(ida_modules): print("ข้อผิดพลาด: ฟังก์ชัน IDA เรียกว่านอกบริบท IDA!") เพิ่ม NotImplementedError return func(*args, **kwargs) return cast(FuncT, wrapper_ida_check)class OPERAND_TYPE(Enum): o_void = 0 o_reg = 1 o_mem = 2 o_phrase = 3 o_displ = 4 o_imm = 5 o_far = 6 o_near = 7 o_idpspec0 = 8 o_idpspec1 = 9 o_idpspec2 = 10 o_idpspec3 = 11 o_idpspec4 = 12 o_idpspec5 = 13Addr = NewType("Addr",int)# Functableclass Functable (ABC): @abstractmethod def funcname_from_offset (ตนเอง, addr: Addr) -> str: เพิ่ม NotImplementedError @abstractmethod def as_dict (ตนเอง) -> Dict [Addr, str]: เพิ่ม NotImplementedError @ida @abstractmethod def ida_struct_id (ตนเอง) -> int: เพิ่ม NotImplementedError @abstractclassmethod def from_file (cls, fname: str) -> "Functable": เพิ่ม NotImplementedErrorclass _Functable (Functable): def __init__ (ตนเอง, ฐาน: Addr, addr_contents: รายการ [Tuple [Addr, str]] ) -> ไม่มี: self.base = base self.content_by_addr = {k: v สำหรับ (k,v) ใน addr_contents} self.struct_id = ไม่มี def funcname_from_offset (self, offset: int) -> str: return self.content_by_addr [ Addr(self.base+offset)] def as_dict(self) -> Dict[Addr, str]: return self.content_by_addr @ida def ida_struct_id(self) -> int: ถ้า self.struct_id เป็นไม่มี: self.struct_id = ida_struct .add_struc(ida_idaapi.BADADDR, "FuncTable", False) struct_ptr = ida_struct.get_struc(self.struct_id) สำหรับ (addr, funcname) ใน sorted(self.as_dict().items(), key = lambda item: item[0 ]): ida_struct.add_struc_member(struct_ptr, funcname, addr-self.base, ida_bytes.dword_flag(), None, 4) return self.struct_id #type: ละเว้น @classmethod def from_file(cls, fname: str) -> "_Functable ": ด้วย open(fname, "r") เป็น fh: tokenized_entrylist = [line.strip().split(" ") สำหรับบรรทัดใน fh.readlines()] base = Addr(int(tokenized_entrylist[0][0] ,16)) addr_contents : List[Tuple[Addr,str]] = [] สำหรับ tokenized_entry ใน tokenized_entrylist: ถ้า len(tokenized_entry) > 2: addr_contents.append(( Addr(int(tokenized_entry[0],16)), tokenized_entry [2].replace("!","_") )) return _Functable(base, addr_contents)#CoinLoaderFunctionclass CoinLoaderFunction(ABC): @ida @abstractmethod def functable_register(self) -> Optional[str]: ยก NotImplementedError @ida @abstractmethod def heads(self) -> List[Addr]: Raise NotImplementedError @ida @abstractmethod def is_indirect_call(self, addr: Addr) -> bool: Raise NotImplementedError @ida @abstractmethod def all_indirect_calls(self) -> Dict[Addr, int]: เพิ่ม NotImplementedError @ida @abstractmethod def patch_single_indirect_call (self, ea: Addr, ft: Funcable) -> ไม่มี: เพิ่ม NotImplementedError @ida @abstractmethod def patch_indirect_calls (self, ft: Functable) -> ไม่มี: เพิ่ม NotImplementedError @ida @ abstractclassmethod def from_addr(cls, addr: Addr) -> "CoinLoaderFunction": เพิ่ม NotImplementedErrorclass _CoinLoaderFunction (CoinLoaderFunction): @ida def __init__ (self, addr: Addr) -> ไม่มี: self.addr = addr self._functable_register = self.functable_register () @ida def heads(self) -> List[Addr]: return [insn for bound in idautils.Chunks(self.addr) for insn in idautils.Heads(*bound)] @ida def is_regload_insn(self, ea: Addr) -> bool: if idc.print_insn_mnem(ea) != "mov": return False for i in (0,1): if OPERAND_TYPE(idc.get_operand_type(ea,i)) != OPERAND_TYPE.o_reg: return False ถ้า idc.print_operand(ea,1) != "ecx": return False return True @ida def functable_register(self) -> Optional[str]: try: regload_insn = next(filter(self.is_regload_insn, self.heads() )) return idc.print_operand(regload_insn,0) #type: ละเว้นยกเว้น StopIteration: return none @ida def is_indirect_call(self, ea: Addr) -> bool: if self._functable_register is None: return False if idc.print_insn_mnem(ea ) != "call": ส่งคืน False หาก OPERAND_TYPE(idc.get_operand_type(ea,0)) != OPERAND_TYPE.o_displ: ส่งคืน False หากไม่ใช่ idc.print_operand(ea,0).startswith("dword ptr ["+self. _functable_register+"+"): return False return True @ida def all_indirect_calls(self) -> Dict[Addr,int]: eas = [h สำหรับ h ใน self.heads() ถ้า self.is_indirect_call(h)] กลับ {ea: idc.get_operand_value(ea,0) for ea in eas} @ida def patch_single_indirect_call (self, ea: Addr, ft: Funcable) -> ไม่มี: sid = ft.ida_struct_id() ถ้า sid เป็นไม่มี: print ("ไม่สามารถแก้ไข, functable ไม่มี IDA struct") print("Use: funcable.create_struct()") idc.op_stroff(ea, 0, sid,0) @ida def patch_indirect_calls(self, ft: Funcable) -> ไม่มี: สำหรับการโทร ใน self.all_indirect_calls(): self.patch_single_indirect_call(โทร,ฟุต) @ida @classmethod def from_addr(cls, addr: Addr) -> "CoinLoaderFunction": return _CoinLoaderFunction(addr)def patch_indirect_calls_all_functions(ft: Functable): สำหรับ ea ใน idautils.Functions(): clf : CoinLoaderFunction = _CoinLoaderFunction(ea) clf.patch_indirect_calls(ft)def test_get_name() -> ไม่มี: f = _Functable.from_file("funcable.txt") assert(f.funcname_from_offset(0x0) == "kernel32_OpenProcess") ยืนยัน (f.funcname_from_offset (0x4) == "kernel32_VirtualProtect")

ตารางฟังก์ชันตัวอย่าง:

0x26cfb94 0x7dd71986 OpenProcess0x26cfb98 0x7dd7435f VirtualProtect0x26cfb9c 0x7dd711c0 GetLastError_00x26cfba0 0x7dd74913 LoadLibraryExA0x26cfba4 0x7dd8e4be GlobalReAlloc0x26cf ba8 0x7dd7588e GlobalAlloc0x26cfbac 0x7dd734d5 CreateThread0x26cfbb0 0x7dd8d16f GlobalSize0x26cfbb4 0x7dd7492b LoadLibraryW_00x26cfbb8 0x7dd71856 VirtualAlloc0x26cfbbc 0x7dd71072 CreatePro cessA0x26cfbc0 0x7dd7495d LoadLibraryExW0x26cfbc4 0x7dd77a10 ExitProcess0x26cfbc8 0x7dd732bb SetThreadPriority0x26cfbcc 0x7dd7186e VirtualFree0x26cfbd0 0x7dd7168c LocalAlloc_00x26cfbd4 0x7dd734c8 FreeLibrary_00x26cfbd8 0x7dd75558 GlobalFree0x26cfbdc 0x7dd72d3c LocalFree0x26cfbe0 0x7ddeaeee ตั้งไฟล์เสร็จสิ้นการแจ้งเตือนโหมด 0x26cfbe4 0x7dd8cf28 SetPriorityClass0x26cfbe8 0x7dd9310 2 lstrcpyW0x26cfbec 0x7dd75971 ค้นหาทรัพยากร W0x26cfbf0 0x7dd8ecbb SetFileTime0x26cfbf4 0x7dd71809 GetCurrentProcess_00x26cfbf8 0x7dd7e2ce FindFirstFileA0x26cfbfc 0x7dd8e9bb FindResourceA0x26cfc00 0x7dd734b0 GetModuleHandleW0x26cfc04 0x7dd741f0 แบบสอบถามประสิทธิภาพความถี่ 0x26cfc08 0x7dd9d53e ค้นหา NextFileA 0x26cfc0c 0x7dd75444 DeleteFileA0x26cfc10 0x7dd9cb05 RegisterWaitForSingleObject0x26cfc14 0x7ddf453f SetNamedPipeHandleState0x26cfc18 0x7dd9691f K32EnumProcesses0x26cfc1c 0x7dd8d3ab ReleaseSemaphore0 x26cfc20 0x7dd75a4b lstrlen0x26cfc24 0x7df720c0 0x26cfc28 0x7dd8192a lstrcpyn0x26cfc2c 0x7dd997aa GetSystemWindowsDirectoryA0x26cfc30 0x7ddf1807 CreateNamedPipeA0x26cfc34 0x7 dd743ef ResumeThread0x26cfc38 0x7dd75ac9 ขนาดของทรัพยากร 0x26cfc3c 0x7dd749ca GetSystemInfo0x26cfc40 0x7dd71282 WriteFile0x26cfc44 0x7dd73f5c CreateFileW0x26cfc48 0x7dd75959 LockResource0x26cfc4c 0 x7dd7170d WideCharToMultiByte_00x26cfc50 0x7dd716c5 SetEvent0x26cfc54 0x7ddf498e แบบสอบถามFullProcessImageNameA0x26cfc58 0x7dd71725 QueryPerformanceCounter_00x26cfc5c 0x7dd905a0 SetThreadAffinityMask0x26cfc60 0x7ddf44bf RemoveDirectoryA0x26cfc64 0x7dd8ca5a สร้าง SemaphoreW0x26cfc68 0x7dd717ec GetCurrentThread0x26cfc6c 0x7dd74f2b Fl sAlloc0x26cfc70 0x7dd7183e CreateEventW0x26cfc74 0x7dd751a1 GetCommandLineA0x26cfc78 0x7dd8b6e0 GetComputerNameA0x26cfc7c 0x7dd75611 GetCurrentDirectoryW0x26cfc80 0x7dd8eceb lstrcmp0x26cfc84 0x7dd92a9d lstrcpy0x26cfc88 0x7dd74208 FlsSetValue0x26cfc8c 0x7ddfe6ab ยกเลิกการลงทะเบียนWait0x26cfc90 0x7dd71245 GetModuleHandleA0x26cfc94 0x7dd9276c GetTempPathA0x26cfc98 0x7dd8ec d3 SetFileAttributesA0x26cfc9c 0x7dd7195e IsWow64Process0x26cfca0 0x7dd7469b FlushFileBuffers0x26cfca4 0x7dd75a7e SystemTimeToFileTime0x26cfca8 0x7dde3161 EnumResourceNamesW0x26cfcac 0x7dd8d650 Wow64DisableWow64FsRedirection0x26cfcb0 0x7ddf40fb ConnectNamedPipe0x26cfcb4 0x7dd71b00 SetErrorMode0x26cfcb8 0x7dd8eef2 CreateIoCompletionPort0x26cfcbc 0x7dd75aa6 GetLocalTime0x26cfcc0 0x7dd74c6b CreateMutexA0x26cfcc4 0x7dd7192e MultiByteToWideChar_00x26cfcc8 0x7dd7594c LoadResource0x26cfccc 0x7dd74950 GetModuleFileNameW_00x26cfcd0 0x7dd8d3c3 GetQueued สถานะความสมบูรณ์0x26cfcd4 0x7dd71410 CloseHandle_00x26cfcd8 0x7dd7359f FlsFree0x26cfcdc 0x7dd8195c SetHandleInformation0x26cfce0 0x7dd710ff Sleep_00x26cfce4 0x7dd714b1 GetModuleFileNameA0x26cf ce8 0x7dd8d668 Wow64RevertWow64FsRedirection0x26cfcec 0x7dd96dcb GetVolumeInformationA0x26cfcf0 0x7dd75a96 GetSystemTime0x26cfcf4 0x7dd73ed3 อ่านไฟล์0x26cfcf8 0x7dd9d526 CreateDirectoryA0x26cfcfc 0x7dd 7110c GetTickCount_00x26cfd00 0x7dd73e8e lstrcmpiA0x26cfd04 0x7dd9ab72 EnumResourceNamesA0x26cfd08 0x7dd754ee ค้นหาไฟล์ถัดไปW0x26cfd0c 0x7ddf41df DisconnectNamedPipe0x26cfd10 0x7dd7 4435 FindFirstFileW0x26cfd14 0x7dd8eb39 ExpandEnvironmentStringsA0x26cfd18 0x7dd75414 GetFileAttributesA0x26cfd1c 0x7dd74220 WaitForMultipleObjects0x26cfd20 0x7dd8d802 TerminateProcess_00x26cfd24 0x7dd74442 FindClose0x26cfd28 0x7dded911 MoveFileA0x26cfd2c 0x7dd753c6 CreateFileA0x26cfd30 0x7ddf43af GetQueuedCompletionStatusEx0x26cfd34 0x7dd789b3 DeleteFileW0 x26cfd38 0x7dd8ef29 PostQueuedCompletionStatus0x26cfd3c 0x7dd74173 ExpandEnvironmentStringsW0x26cfd40 0x7dd74407 GetFileTime0x26cfd44 0x7dd71136 WaitForSingleObject0x26cfd48 0x7dd716dd รีเซ็ตเหตุการณ์ 0x26c fd4c 0x7dd71252 FlsGetValue0x26cfd50 0x7dd717d1 SetFilePointer0x26cfd54 0x7dd71700 lstrlenW_00x26cfd58 0x7dd8efec สลับไปที่Thread0x26cfd5c 0x77c69edf SetSecurityInfo0x26cfd6 0 0x77c8077c LsaOpenPolicy0x26cfd64 0x77c740e6 จัดสรรและเตรียมใช้งาน Sid0x26cfd68 0x77c740fe RegCreateKeyExW0x26cfd6c 0x77c741b3 ค้นหาสิทธิพิเศษค่าW0x26cfd70 0x77c7431c GetTokenInformation0x26cfd74 0x77cb15a0 SetNamedSecurityInfoA0x26cfd78 0x77c7469d RegCloseKey_00x26cfd7c 0x77c81af7 LsaClose0x26cfd80 0x77c74620 เตรียมใช้งานSecurityDescriptor0x26cfd84 0x77c 7468d RegOpenKeyExW_00x26cfd88 0x77c714d6 RegSetValueExW0x26cfd8c 0x77ca8819 LsaAddAccountRights0x26cfd90 0x77cb15e9 SetEntriesInAclA0x26cfd94 0x77c7412e FreeSid0x26cfd98 0 x77c7418e AdjustTokenPrivileges0x26cfd9c 0x77cb187f รับรายการที่ชัดเจนจาก AclA0x26cfda0 0x77c715ad RegOpenCurrentUser0x26cfda4 0x77c7157a GetUserNameW0x26cfda8 0x77c7415e SetSecurityDescriptorDacl0x26 cfdac 0x77c60000 0x26cfdb0 0x77c74304 OpenProcessToken0x26cfdb4 0x77cb1554 GetNamedSecurityInfoA0x26cfdb8 0x7deb01e3 0x26cfdbc 0x7debd2f3 0x26cfdc0 0x7dea9c7 0 0x26cfdc4 0x7de922b0 0x26cfdc8 0x7de70000 0x26cfdcc 0x7deec240 0x26cfdd0 0x7dea2265 0x26cfdd4 0x7debc4ca 0x26cfdd8 0x7dea45f5 0x26cfddc 0x7de92340 0x26cfde0 0x7de92270 0x26cfde4 0x7debca3a 0x26cfde8 0x7de9df20 0x26cfdec 0x7dea2500 0x26cfdf0 0x7dea2c42 0x26cfdf4 0x7deebfa0 0x26cfdf8 0x7dcbfd3f MessageBoxW0x26cfdfc 0x7dcbfd1e MessageBoxA0x26cfe00 0x7dc70a19 GetDesk topWindow0x26cfe04 0x7dc8e061 wsprintfW0x26cfe08 0x7dc50000 ลำดับ24470x26cfe0c 0x7dc7ae5f wsprintfA0x26cfe10 0x72589d0b CoCreateInstance0x26cfe14 0x72540000 0x26cfe18 0x72567259 กำหนดค่าเริ่มต้นความปลอดภัย 0x26cfe1c 0x725809ad กำหนดค่าเริ่มต้นร่วมEx0x26cfe20 0x72555ea5 CoSetProxyBlanket0x26cfe24 0x725886d3 Coกำหนดค่าเริ่มต้น 0x26cfe28 0x6fc33e59 SysFree String0x26cfe2c 0x6fc34642 SysAllocString0x26cfe30 0x6fc30000 Ordinal4710x26cfe34 0x504b30 0x26cfe38 0x504b58 0x26cfe3c 0x535120 aAmdRyzen536006_00x26cfe40 0x1 0x26cfe44 0x712175e8 InternetSetOptionA0x26cfe48 0x7127a920 InternetGetLastResponseInfoA0x26cfe4c 0xcc0004 0x26cfe50 0x7121b406 InternetReadFile0x26cfe54 0x712430f1 InternetOpenUrlA0x26cfe58 0x7122f18e InternetOpenA0x26cfe5c 0x71224c7d HttpOpenRequestA0x26cfe60 0x712249e9 InternetConnectA0x26c fe64 0x71200000 Ordinal3670x26cfe68 0x7121ab49 InternetCloseHandle0x26cfe6c 0x71211b56 InternetQueryOptionA0x26cfe70 0x712918f8 HttpSendRequestA0x26cfe74 0x6dc00000 0x26cfe78 0x 6dc2a9bc DnsQuery_A0x26cfe7c 0x6dc0436b DnsFree0x26cfe80 0x7d830000 0x26cfe84 0x7d83647a BCryptตรวจสอบลายเซ็น0x26cfe88 0x7d834d42 BCryptImportKey0x26cfe8c 0x7d 831fbc BCryptGenerateSymmetricKey0x26cfe90 0x7d831b44 BCryptFinishHash0x26cfe94 0x7d831a5f BCryptDestroyHash0x26cfe98 0x7d831b93 BCryptCreateHash0x26cfe9c 0x7d831b0b BCry ptHashData0x26cfea0 0x7d8318b8 BCryptDecrypt0x26cfea4 0x7d83195c BCryptEncrypt0x26cfea8 0x7d8320d4 BCryptSetProperty0x26cfeac 0x7d83234e BCryptCloseAlgorithmProvider0x26cfeb0 0x7 d834f94 BCryptImportKeyPair0x26cfeb4 0x7d83519b BCryptExportKey0x26cfeb8 0x7d831ca7 BCryptGetProperty0x26cfebc 0x7d831f40 BCryptDestroyKey0x26cfec0 0x7d832d30 BCryptOpenAlgorithmProvider

References

Top Articles
Latest Posts
Article information

Author: Errol Quitzon

Last Updated: 11/29/2023

Views: 5823

Rating: 4.9 / 5 (59 voted)

Reviews: 90% of readers found this page helpful

Author information

Name: Errol Quitzon

Birthday: 1993-04-02

Address: 70604 Haley Lane, Port Weldonside, TN 99233-0942

Phone: +9665282866296

Job: Product Retail Agent

Hobby: Computer programming, Horseback riding, Hooping, Dance, Ice skating, Backpacking, Rafting

Introduction: My name is Errol Quitzon, I am a fair, cute, fancy, clean, attractive, sparkling, kind person who loves writing and wants to share my knowledge and understanding with you.