<div class="xblock xblock-public_view xblock-public_view-vertical" data-course-id="course-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1" data-init="VerticalStudentView" data-runtime-class="LmsRuntime" data-runtime-version="1" data-block-type="vertical" data-usage-id="block-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1+type@vertical+block@99ee0b70ddc84bc68ab4c873548c6941" data-request-token="2a99678e095b11efabb30242ac12000b" data-graded="True" data-has-score="False">
<div class="vert-mod">
<div class="vert vert-0" data-id="block-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1+type@markdown+block@7b4cb2cb0b8243fdac73a86c451ef921">
<div class="xblock xblock-public_view xblock-public_view-markdown" data-course-id="course-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1" data-block-type="markdown" data-usage-id="block-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1+type@markdown+block@7b4cb2cb0b8243fdac73a86c451ef921" data-request-token="2a99678e095b11efabb30242ac12000b" data-graded="True" data-has-score="False">
<div class="markdown_xblock"><p>UEFI Shell commands are like small application built-in to the UEFI Shell Application. To enter the UEFI Shell in the case of our QEMU+OVFM setup, we would just boot the platform and wait for Shell. Since it would be selected according to boot order.</p>
<h2>Exercise #1: Enter UEFI Shell</h2>
<pre><code>qemu-system-x86_64 -nographic -bios Build/OvmfX64/DEBUG_GCC5/FV/OVMF.fd -chardev file,path=debug.log,id=edk2-debug -device isa-debugcon,iobase=0x402,chardev=edk2-debug
</code></pre>
<p>After some time you should see:</p>
<pre><code>BdsDxe: failed to load Boot0001 "UEFI QEMU DVD-ROM QM00003 " from PciRoot(0x0)/Pci(0x1,0x1)/Ata(Secondary,Master,0x0): Not Found
>>Start PXE over IPv4.
</code></pre>
<p>and after PXE loading failure</p>
<pre><code>UEFI Interactive Shell v2.2
EDK II
UEFI v2.70 (EDK II, 0x00010000)
Mapping table
BLK0: Alias(s):
PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0)
Press ESC in 1 seconds to skip startup.nsh or any other key to continue.
Shell>
</code></pre>
<ul>
<li>To list all available commands simply type <code>help</code>. Get familiar with available commands. Please note not all command are available in all versions of UEFI Shell. Available commands are selected at build time in EDKII.</li>
</ul>
<pre><code>Shell> help
alias - Displays, creates, or deletes UEFI Shell aliases.
attrib - Displays or modifies the attributes of files or directories.
bcfg - Manages the boot and driver options that are stored in NVRAM.
cd - Displays or changes the current directory.
cls - Clears the console output and optionally changes the background and foreground color.
comp - Compares the contents of two files on a byte-for-byte basis.
connect - Binds a driver to a specific device and starts the driver.
cp - Copies one or more files or directories to another location.
date - Displays and sets the current date for the system.
dblk - Displays one or more blocks from a block device.
devices - Displays the list of devices managed by UEFI drivers.
devtree - Displays the UEFI Driver Model compliant device tree.
dh - Displays the device handles in the UEFI environment.
disconnect - Disconnects one or more drivers from the specified devices.
dmem - Displays the contents of system or device memory.
dmpstore - Manages all UEFI variables.
drivers - Displays the UEFI driver list.
drvcfg - Invokes the driver configuration.
drvdiag - Invokes the Driver Diagnostics Protocol.
echo - Controls script file command echoing or displays a message.
edit - Provides a full screen text editor for ASCII or UCS-2 files.
eficompress - Compresses a file using UEFI Compression Algorithm.
efidecompress - Decompresses a file using UEFI Decompression Algorithm.
else - Identifies the code executed when 'if' is FALSE.
endfor - Ends a 'for' loop.
endif - Ends the block of a script controlled by an 'if' statement.
exit - Exits the UEFI Shell or the current script.
for - Starts a loop based on 'for' syntax.
getmtc - Gets the MTC from BootServices and displays it.
goto - Moves around the point of execution in a script.
help - Displays the UEFI Shell command list or verbose command help.
hexedit - Provides a full screen hex editor for files, block devices, or memory.
http - Download a file from HTTP server.
if - Executes commands in specified conditions.
ifconfig - Modifies the default IP address of the UEFI IPv4 Network Stack.
initrd - Registers or unregisters a file as Linux initrd.
load - Loads a UEFI driver into memory.
loadpcirom - Loads a PCI Option ROM.
ls - Lists the contents of a directory or file information.
map - Displays or defines file system mappings.
memmap - Displays the memory map maintained by the UEFI environment.
mkdir - Creates one or more new directories.
mm - Displays or modifies MEM/MMIO/IO/PCI/PCIE address space.
mode - Displays or changes the console output device mode.
mv - Moves one or more files to a destination within or between file systems.
openinfo - Displays the protocols and agents associated with a handle.
parse - Retrieves a value from a standard format output file.
pause - Pauses a script and waits for an operator to press a key.
pci - Displays PCI device list or PCI function configuration space and PCIe extended configuration space.
ping - Ping the target host with an IPv4 stack.
reconnect - Reconnects drivers to the specific device.
reset - Resets the system.
rm - Deletes one or more files or directories.
sermode - Sets serial port attributes.
set - Displays or modifies UEFI Shell environment variables.
setsize - Adjusts the size of a file.
setvar - Displays or modifies a UEFI variable.
shift - Shifts in-script parameter positions.
smbiosview - Displays SMBIOS information.
stall - Stalls the operation for a specified number of microseconds.
tftp - Download a file from TFTP server.
time - Displays or sets the current time for the system.
timezone - Displays or sets time zone information.
touch - Updates the filename timestamp with the current system date and time.
type - Sends the contents of a file to the standard output device.
unload - Unloads a driver image that was already loaded.
ver - Displays UEFI Firmware version information.
vol - Displays or modifies information about a disk volume.
Help usage:help [cmd|pattern|special] [-usage] [-verbose] [-section name][-b]
</code></pre>
<ul>
<li>Based on number of commands we can easily say this is very simple OS-like environment similar to DOS. But what is more important it runs in ring 0, so it is highly priviledged.</li>
<li>Try to read help for some commands and get through all documentation sections.</li>
</ul>
</div>
</div>
</div>
<div class="vert vert-1" data-id="block-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1+type@done+block@0746fb2197a74710933e51c345f60098">
<div class="xblock xblock-public_view xblock-public_view-done" data-course-id="course-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1" data-block-type="done" data-usage-id="block-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1+type@done+block@0746fb2197a74710933e51c345f60098" data-request-token="2a99678e095b11efabb30242ac12000b" data-graded="True" data-has-score="True">
<div class="page-banner"><div class="alert alert-warning"><span class="icon icon-alert fa fa fa-warning" aria-hidden="true"></span><div class="message-content">Completion is only accessible to enrolled learners. Sign in or register, and enroll in this course to view it.</div></div></div>
</div>
</div>
<div class="vert vert-2" data-id="block-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1+type@discussion+block@7ae56e72d04a46d4b2a4cddec05fb26c">
<div class="xblock xblock-public_view xblock-public_view-discussion" data-course-id="course-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1" data-block-type="discussion" data-usage-id="block-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1+type@discussion+block@7ae56e72d04a46d4b2a4cddec05fb26c" data-request-token="2a99678e095b11efabb30242ac12000b" data-graded="True" data-has-score="False">
<div class="page-banner"><div class="alert alert-warning"><span class="icon icon-alert fa fa fa-warning" aria-hidden="true"></span><div class="message-content">Discussion is only accessible to enrolled learners. Sign in or register, and enroll in this course to view it.</div></div></div>
</div>
</div>
</div>
<script type="text/javascript">
(function (require) {
require(['/static/js/dateutil_factory.be68acdff619.js?raw'], function () {
require(['js/dateutil_factory'], function (DateUtilFactory) {
DateUtilFactory.transform('.localized-datetime');
});
});
}).call(this, require || RequireJS.require);
</script>
<script>
function emit_event(message) {
parent.postMessage(message, '*');
}
</script>
</div>
<div class="xblock xblock-public_view xblock-public_view-vertical" data-course-id="course-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1" data-init="VerticalStudentView" data-runtime-class="LmsRuntime" data-runtime-version="1" data-block-type="vertical" data-usage-id="block-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1+type@vertical+block@9fc663038ead40afb82cdbb3aed8c84b" data-request-token="2a99678e095b11efabb30242ac12000b" data-graded="True" data-has-score="False">
<div class="vert-mod">
<div class="vert vert-0" data-id="block-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1+type@markdown+block@297a73541e94461eb98031cd2f7cbefd">
<div class="xblock xblock-public_view xblock-public_view-markdown" data-course-id="course-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1" data-block-type="markdown" data-usage-id="block-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1+type@markdown+block@297a73541e94461eb98031cd2f7cbefd" data-request-token="2a99678e095b11efabb30242ac12000b" data-graded="True" data-has-score="False">
<div class="markdown_xblock"><h2>Exercise #2: list all block devices</h2>
<ul>
<li>From Exercise #1 you may recall <code>map</code> command, which shows exisiing block devices and filesystems:</li>
</ul>
<pre><code>Shell> map
Mapping table
BLK0: Alias(s):
PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0)
</code></pre>
<ul>
<li><code>map -r</code> is very useful to detect hotplugged devices, since UEFI does enumeration just once</li>
<li>Let's check how the block devices listed change when we will add a file as a USB device. We have to start from runing qemu with USB XHCI controller</li>
</ul>
<pre><code>qemu-system-x86_64 -nographic -bios Build/OvmfX64/DEBUG_GCC5/FV/OVMF.fd -chardev file,path=debug.log,id=edk2-debug -device isa-debugcon,iobase=0x402,chardev=edk2-debug -device qemu-xhci,id=xhci
</code></pre>
<ul>
<li>Check <code>map</code> output</li>
</ul>
<pre><code>Mapping table
BLK0: Alias(s):
PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0) BLK1: Alias(s):
PciRoot(0x0)/Pci(0x4,0x0)/USB(0x0,0x0)
</code></pre>
<ul>
<li>In other terminal let's create FAT32 image that will be used as USB stick:</li>
</ul>
<pre><code>user@user-OST-VM:~$ qemu-img create -f raw /tmp/usb.img 128M
Formatting '/tmp/usb.img', fmt=raw size=134217728
user@user-OST-VM:~$ mkfs.vfat -F32 /tmp/usb.img
mkfs.fat 4.1 (2017-01-24)
</code></pre>
<ul>
<li>Enter QEMU Monitor (<code>Ctrl-a c</code>) and add USB stick</li>
</ul>
<pre><code>(qemu) drive_add 0 if=none,id=stick,format=raw,file=/tmp/usb.img
OK
(qemu) device_add usb-storage,id=ost2,bus=xhci.0,drive=stick
</code></pre>
<ul>
<li>Let's get back to our UEFI Shell, by <code>Ctrl-a c</code>, to clean screen use <code>cls</code> command</li>
<li>Let's run <code>map</code> again. It looks like nothing happen?</li>
<li>Let's use <code>map -r</code>:</li>
</ul>
<pre><code>Shell> map -r
Mapping table
FS0: Alias(s):HD1a0:;BLK1:
PciRoot(0x0)/Pci(0x4,0x0)/USB(0x0,0x0)
BLK0: Alias(s):
PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0)
</code></pre>
<p>As we can see <code>FS0</code> appeared under <code>BLK1</code> device.</p>
<ul>
<li>We would see similar behavior with real hardware.</li>
</ul>
</div>
</div>
</div>
<div class="vert vert-1" data-id="block-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1+type@done+block@39d7f7d65fca4129a181d72313260b2e">
<div class="xblock xblock-public_view xblock-public_view-done" data-course-id="course-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1" data-block-type="done" data-usage-id="block-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1+type@done+block@39d7f7d65fca4129a181d72313260b2e" data-request-token="2a99678e095b11efabb30242ac12000b" data-graded="True" data-has-score="True">
<div class="page-banner"><div class="alert alert-warning"><span class="icon icon-alert fa fa fa-warning" aria-hidden="true"></span><div class="message-content">Completion is only accessible to enrolled learners. Sign in or register, and enroll in this course to view it.</div></div></div>
</div>
</div>
<div class="vert vert-2" data-id="block-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1+type@discussion+block@a28fa3ed4141457d940027294b79896f">
<div class="xblock xblock-public_view xblock-public_view-discussion" data-course-id="course-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1" data-block-type="discussion" data-usage-id="block-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1+type@discussion+block@a28fa3ed4141457d940027294b79896f" data-request-token="2a99678e095b11efabb30242ac12000b" data-graded="True" data-has-score="False">
<div class="page-banner"><div class="alert alert-warning"><span class="icon icon-alert fa fa fa-warning" aria-hidden="true"></span><div class="message-content">Discussion is only accessible to enrolled learners. Sign in or register, and enroll in this course to view it.</div></div></div>
</div>
</div>
</div>
<script type="text/javascript">
(function (require) {
require(['/static/js/dateutil_factory.be68acdff619.js?raw'], function () {
require(['js/dateutil_factory'], function (DateUtilFactory) {
DateUtilFactory.transform('.localized-datetime');
});
});
}).call(this, require || RequireJS.require);
</script>
<script>
function emit_event(message) {
parent.postMessage(message, '*');
}
</script>
</div>
<div class="xblock xblock-public_view xblock-public_view-vertical" data-course-id="course-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1" data-init="VerticalStudentView" data-runtime-class="LmsRuntime" data-runtime-version="1" data-block-type="vertical" data-usage-id="block-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1+type@vertical+block@8e20ebdfb7be46b5a7a3007475a40f1b" data-request-token="2a99678e095b11efabb30242ac12000b" data-graded="True" data-has-score="False">
<div class="vert-mod">
<div class="vert vert-0" data-id="block-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1+type@markdown+block@1c36d616942b4b8183c28c32539acaea">
<div class="xblock xblock-public_view xblock-public_view-markdown" data-course-id="course-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1" data-block-type="markdown" data-usage-id="block-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1+type@markdown+block@1c36d616942b4b8183c28c32539acaea" data-request-token="2a99678e095b11efabb30242ac12000b" data-graded="True" data-has-score="False">
<div class="markdown_xblock"><h2>Exercise #3: Run UEFI Self-Certification Test (SCT)</h2>
<ul>
<li>SCT can be used to evaluate quality of UEFI implementation</li>
<li>Let's obtain SCT:</li>
</ul>
<div class="codehilite">
<pre><span></span><code>wget https://github.com/tianocore/edk2-test/releases/download/edk2-test-stable202108/UefiSctBinaryX64.zip
unzip UefiSctBinaryX64.zip
</code></pre>
</div>
<p>(<a href="https://gitlab.com/opensecuritytraining/arch4021-intro-uefi-additional-files/-/blob/master/UefiSctBinaryX64.zip">Mirror copy of UefiSctBinaryX64.zip incase the above link breaks</a>)</p>
<ul>
<li>Mount our USB disk image and copy SCT to it</li>
</ul>
<div class="codehilite">
<pre><span></span><code>sudo mount /tmp/usb.img /media
sudo cp -r SctPackageX64/ /media
sudo umount /media
</code></pre>
</div>
<ul>
<li>Boot QEMU with USB connected</li>
</ul>
<div class="codehilite">
<pre><span></span><code>UEFI Interactive Shell v2.2
EDK II
UEFI v2.70 <span class="o">(</span>EDK II, 0x00010000<span class="o">)</span>
Mapping table
FS0: Alias<span class="o">(</span>s<span class="o">)</span>:HD1a0:<span class="p">;</span>BLK1:
PciRoot<span class="o">(</span>0x0<span class="o">)</span>/Pci<span class="o">(</span>0x4,0x0<span class="o">)</span>/USB<span class="o">(</span>0x0,0x0<span class="o">)</span>
BLK0: Alias<span class="o">(</span>s<span class="o">)</span>:
PciRoot<span class="o">(</span>0x0<span class="o">)</span>/Pci<span class="o">(</span>0x1,0x1<span class="o">)</span>/Ata<span class="o">(</span>0x0<span class="o">)</span>
Press ESC <span class="k">in</span> <span class="m">1</span> seconds to skip startup.nsh or any other key to <span class="k">continue</span>.
Shell> fs0:
FS0:<span class="se">\></span> ls
Directory of: FS0:<span class="se">\ </span>
<span class="m">09</span>/08/2021 <span class="m">09</span>:19 <DIR> <span class="m">512</span> SctPackageX64
<span class="m">1</span> Dir<span class="o">(</span>s<span class="o">)</span>
FS0:<span class="se">\></span> <span class="nb">cd</span> SctPackageX64
FS0:<span class="se">\S</span>ctPackageX64<span class="se">\></span> ls Directory of: FS0:<span class="se">\S</span>ctPackageX64<span class="se">\ </span>
<span class="m">06</span>/01/2022 <span class="m">22</span>:08 <DIR> <span class="m">512</span> .
<span class="m">06</span>/01/2022 <span class="m">22</span>:08 <DIR> <span class="m">0</span> ..
<span class="m">09</span>/08/2021 <span class="m">09</span>:16 <span class="m">32</span>,800 InstallX64.efi
<span class="m">06</span>/10/2021 <span class="m">08</span>:46 <span class="m">1</span>,505 SctStartup.nsh
<span class="m">09</span>/08/2021 <span class="m">09</span>:19 <DIR> <span class="m">1</span>,024 X64
</code></pre>
</div>
<ul>
<li>Run <code>InstallX64.efi</code> and select index 1 for FS0. It will create a directory in <code>FS0:\</code> and <code>startup.nsh</code> script which will be used after reboot.</li>
<li>Go to <code>FS0:\SCT</code> and run <code>SCT.efi -u</code> - this is nice terminal UI to configure test. We will not use it, but it could be useful for test results analysis. Exit from terminal UI, by hitting <code>Esc</code></li>
<li>Running full test suite using <code>SCT.efi -a</code> hangs in QEMU (at least it hanged for me) after around 10 hours of execution. <code>-v</code> should accelerate execution 70-80% but it is still a lot.</li>
<li>So, let's try some subset through sequence file:</li>
</ul>
<div class="codehilite">
<pre><span></span><code>FS0:<span class="se">\S</span>ct<span class="se">\></span> SCT.efi -u
</code></pre>
</div>
<ul>
<li>Go to <code>Test Case Management->GenericTest->EfiCompliantTest</code> and highlight <code>PlatformSpecificElements</code>.</li>
<li>Let's run that test case. Things would be easy if we could just hit <code>F9</code> as application bottom bar say, unfortunately in our case it will send different characters to SCT which will lead to setting 20 iteration without exiting. So we have to use the trick with sending <code>F9</code> from QEMU monitor.</li>
<li>Let's switch to monitor <code>Ctrl-a c</code> and type <code>sendkey f9</code>. This will run tests with result of 13 passes and 15 fails.</li>
<li>Let's get back to main menu and generate test report using <code>Test Report Generator</code>. <code>F2</code> have to be sent using above trick to enter report file name. Test report can be found in <code>FS0:\SCT\Report\<report_name>.csv</code>.</li>
<li>We can also take a look at test logs by using <code>View Test Log</code> and choosing <code>GenericTest->EfiCompliantTest0</code> and file that is inside directory - now you are in primitive editor of UEFI (<code>Ctrl-e</code> for help).</li>
<li>Hit <code>Ctrl-g</code> and give line 167, this should give you following screen.
<img src="https://gitlab.com/opensecuritytraining/arch4021_uefi_intro_slides_and_subtitles/-/raw/main/images/sct_test_log_view.png" alt="" /></li>
</ul>
<h2>Exercise #4: Save sequence file</h2>
<ul>
<li>Run SCT.</li>
<li>Go to <code>Test Case Management->GenericTest->EfiCompliantTest</code> and highlight <code>PlatformSpecificElements</code>.</li>
<li>Now we have to save sequence file. </li>
<li>Let's switch to monitor <code>Ctrl-a c</code> and type <code>sendkey f6</code>, we should see following screen.
<img src="https://gitlab.com/opensecuritytraining/arch4021_uefi_intro_slides_and_subtitles/-/raw/main/images/sct_sendkey_f6.png" alt="" /></li>
<li>Then type <code>sendkey f2</code> and let's switch back (<code>Ctrl-a c</code>) top provide filename <code>ost2</code> and hit <code>Enter</code>, this should give us following screen.
<img src="https://gitlab.com/opensecuritytraining/arch4021_uefi_intro_slides_and_subtitles/-/raw/main/images/sct_seq_save_succeed.png" alt="" /></li>
<li>We should see file in <code>Sequence</code> directory:</li>
</ul>
<div class="codehilite">
<pre><span></span><code>FS0:<span class="se">\S</span>ct<span class="se">\></span> ls Sequence
Directory of: FS0:<span class="se">\S</span>ct<span class="se">\S</span>equence<span class="se">\ </span>
<span class="m">06</span>/01/2022 <span class="m">22</span>:19 <DIR> <span class="m">512</span> .
<span class="m">06</span>/01/2022 <span class="m">22</span>:19 <DIR> <span class="m">8</span>,704 ..
<span class="m">06</span>/02/2022 <span class="m">23</span>:37 <span class="m">171</span>,170 ost2.seq
<span class="m">1</span> File<span class="o">(</span>s<span class="o">)</span> <span class="m">171</span>,170 bytes
<span class="m">2</span> Dir<span class="o">(</span>s<span class="o">)</span>
</code></pre>
</div>
<ul>
<li>It should be possible to run those tests using following command:</li>
</ul>
<div class="codehilite">
<pre><span></span><code>Shell> SCT.efi -s Sequence<span class="se">\o</span>st2.seq
</code></pre>
</div>
<ul>
<li>Unfortunately on QEMU OVFM I cannot make it work, but maybe you can? Anyway it is useful to know how to save sequence file adn run it later.</li>
</ul>
</div>
</div>
</div>
<div class="vert vert-1" data-id="block-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1+type@done+block@bd47d84bb1c441dda8ffed50ad47e05f">
<div class="xblock xblock-public_view xblock-public_view-done" data-course-id="course-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1" data-block-type="done" data-usage-id="block-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1+type@done+block@bd47d84bb1c441dda8ffed50ad47e05f" data-request-token="2a99678e095b11efabb30242ac12000b" data-graded="True" data-has-score="True">
<div class="page-banner"><div class="alert alert-warning"><span class="icon icon-alert fa fa fa-warning" aria-hidden="true"></span><div class="message-content">Completion is only accessible to enrolled learners. Sign in or register, and enroll in this course to view it.</div></div></div>
</div>
</div>
<div class="vert vert-2" data-id="block-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1+type@discussion+block@e9699b8002664a1b9e38fd7c1abacbfe">
<div class="xblock xblock-public_view xblock-public_view-discussion" data-course-id="course-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1" data-block-type="discussion" data-usage-id="block-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1+type@discussion+block@e9699b8002664a1b9e38fd7c1abacbfe" data-request-token="2a99678e095b11efabb30242ac12000b" data-graded="True" data-has-score="False">
<div class="page-banner"><div class="alert alert-warning"><span class="icon icon-alert fa fa fa-warning" aria-hidden="true"></span><div class="message-content">Discussion is only accessible to enrolled learners. Sign in or register, and enroll in this course to view it.</div></div></div>
</div>
</div>
</div>
<script type="text/javascript">
(function (require) {
require(['/static/js/dateutil_factory.be68acdff619.js?raw'], function () {
require(['js/dateutil_factory'], function (DateUtilFactory) {
DateUtilFactory.transform('.localized-datetime');
});
});
}).call(this, require || RequireJS.require);
</script>
<script>
function emit_event(message) {
parent.postMessage(message, '*');
}
</script>
</div>