

{"id":12790,"date":"2020-07-10T11:03:51","date_gmt":"2020-07-10T16:03:51","guid":{"rendered":"https:\/\/rud.is\/b\/?p=12790"},"modified":"2020-07-10T11:03:51","modified_gmt":"2020-07-10T16:03:51","slug":"a-look-at-pan-os-versions-with-a-bit-of-r","status":"publish","type":"post","link":"https:\/\/rud.is\/b\/2020\/07\/10\/a-look-at-pan-os-versions-with-a-bit-of-r\/","title":{"rendered":"A Look at PAN-OS Versions with a Bit of R"},"content":{"rendered":"<p>The incredibly talented folks over at <a href=\"https:\/\/twitter.com\/noperator\">Bishop Fox<\/a> were quite generous this week, providing a <a href=\"https:\/\/github.com\/noperator\/panos-scanner\">scanner for figuring out PAN-OS GlobalProtect<\/a> versions. I&#8217;ve been using their decoding technique and date-based fingerprint table to keep an eye on patch status (over at $DAYJOB we help customers, organizations, and national cybersecurity centers get ahead of issues as best as we can).<\/p>\n<p>We have at-scale platforms for scanning the internet and aren&#8217;t running the <code>panos-scanner<\/code> repo code, but I since there is Python code for doing this, I thought it might be fun to show R folks how to do the same thing and show folks how to use the {httr} package to build something similar (we won&#8217;t hit <a href=\"https:\/\/github.com\/noperator\/panos-scanner\/blob\/master\/panos-scanner.py#L88-L96\">all the URLs<\/a> their script assesses, primarily for brevity).<\/p>\n<h3>What Are We Doing Again?<\/h3>\n<p>Palo Alto makes many things, most of which are built on their custom linux distribution dubbed PAN-OS. One of the things they build is a VPN product that lets users remotely access internal company resources. It&#8217;s <a href=\"https:\/\/security.paloaltonetworks.com\/?severity=CRITICAL&amp;product=PAN-OS&amp;sort=-date\">had quite the number of pretty horrible problems of late<\/a>.<\/p>\n<p>Folks contracted to assess security defenses (colloquially dubbed &#8220;pen-testers&#8221; tho no pens are usually involved) and practitioners within an organization who want to gain an independent view of what their internet perimeter looks like often assemble tools to perform<br \/>\nad-hoc assessments. Sure, there are commercial tools for performing these assessments ($DAYJOB makes some!), but these open source tools make it possible for folks to learn from each other and for makers of products (like PAN-OS) to do a better job securing their creations.<\/p>\n<p>In this case, the creation is a script that lets the caller figure out what version of PAN-OS is running on a given GlobalProtect box.<\/p>\n<p>To follow along at home, you&#8217;ll need access to a PAN-OS system, as I&#8217;m not providing an IP address of one for you. It&#8217;s <em>really not hard to find one<\/em> (just google a bit or stand up a trial one from the vendor). Throughout the examples I&#8217;ll be using {glue} to replace <code>ip<\/code> and <code>port<\/code> in various function calls, so let&#8217;s get some setup bits out of the way:<\/p>\n<pre><code class=\"language-r\">library(httr)\nlibrary(tidyverse) # for read_fwf() (et al), pluck(), filter(), and %&gt;%\n\ngg &lt;- glue::glue # no need to bring in the entire namespace just for this\n<\/code><\/pre>\n<p>Assuming you have a valid <code>ip<\/code> and <code>port<\/code>, let&#8217;s try making a request against your PAN-OS GlobalProtect (hereafter using &#8220;GP&#8221; so save keystrokes) system:<\/p>\n<pre><code class=\"language-r\">httr::HEAD(\n  url = gg(\"https:\/\/{ip}:{port}\/global-protect\/login.esp\")\n) -&gt; res\n## Error in curl::curl_fetch_memory(url, handle = handle) : \n##  SSL certificate problem: self signed certificate\n<\/code><\/pre>\n<p>We&#8217;re using a <a href=\"https:\/\/reqbin.com\/Article\/HttpHead\"><code>HEAD<\/code> request<\/a> as we really don&#8217;t need the contents of the remote file (unless you need to verify it truly is a PAN-OS GP server), just the metadata about it. You can use a traditional <code>GET<\/code> request if you like, though.<\/p>\n<p>We immediately run into a snag since these boxes tend to use a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Self-signed_certificate#:~:text=In%20cryptography%20and%20computer%20security,a%20CA%20aim%20to%20provide.\">self-signed SSL\/TLS certificate<\/a> which web clients aren&#8217;t thrilled about dealing with unless explicitly configured to. We can circumvent this with some configuration options, but you should not use the following incantations haphazardly. SSL\/TLS no longer really means what it used to (thanks, Let&#8217;s Encrypt!) but you have no guarantees of what&#8217;s being delivered to you is legitimate if you hit a plaintext web site or one with an invalid certificate. Enough with the soapbox, let&#8217;s make the request:<\/p>\n<pre><code class=\"language-r\">httr::HEAD(\n  url = gg(\"https:\/\/{ip}:{port}\/global-protect\/login.esp\"),\n  config = httr::config(\n    ssl_verifyhost =FALSE, \n    ssl_verifypeer = FALSE\n  )\n) -&gt; res\n\nhttr::status_code(res)\n## [1] 200\n<\/code><\/pre>\n<p>In that request, we&#8217;ve told the underlying {curl} library calls to not verify the validity of the host or peer certificates associated with the service. Again, don&#8217;t do this haphazardly to get around generic SSL\/TLS problems when making normal API calls or scraping sites.<\/p>\n<p>Since we only made a <code>HEAD<\/code> request, we&#8217;re just getting back headers, so let&#8217;s take a look at them:<\/p>\n<pre><code class=\"language-r\">str(httr::headers(res), 1)\n## List of 18\n##  $ date                     : chr \"Fri, 10 Jul 2020 15:02:32 GMT\"\n##  $ content-type             : chr \"text\/html; charset=UTF-8\"\n##  $ content-length           : chr \"11749\"\n##  $ connection               : chr \"keep-alive\"\n##  $ etag                     : chr \"\\\"7e0d5e2b6add\\\"\"\n##  $ pragma                   : chr \"no-cache\"\n##  $ cache-control            : chr \"no-store, no-cache, must-revalidate, post-check=0, pre-check=0\"\n##  $ expires                  : chr \"Thu, 19 Nov 1981 08:52:00 GMT\"\n##  $ x-frame-options          : chr \"DENY\"\n##  $ set-cookie               : chr \"PHPSESSID=bde5668131c14b765e3e75f8ed5514a0; path=\/; secure; HttpOnly\"\n##  $ set-cookie               : chr \"PHPSESSID=bde5668131c14b765e3e75f8ed5514a0; path=\/; secure; HttpOnly\"\n##  $ set-cookie               : chr \"PHPSESSID=bde5668131c14b765e3e75f8ed5514a0; path=\/; secure; HttpOnly\"\n##  $ set-cookie               : chr \"PHPSESSID=bde5668131c14b765e3e75f8ed5514a0; path=\/; secure; HttpOnly\"\n##  $ set-cookie               : chr \"PHPSESSID=bde5668131c14b765e3e75f8ed5514a0; path=\/; samesite=lax; secure; httponly\"\n##  $ strict-transport-security: chr \"max-age=31536000;\"\n##  $ x-xss-protection         : chr \"1; mode=block;\"\n##  $ x-content-type-options   : chr \"nosniff\"\n##  $ content-security-policy  : chr \"default-src 'self'; script-src 'self' 'unsafe-inline'; img-src * data:; style-src 'self' 'unsafe-inline';\"\n##  - attr(*, \"class\")= chr [1:2] \"insensitive\" \"list\"\n<\/code><\/pre>\n<p>As an aside, I&#8217;ve always found the use of PHP code in security products quite, er, <em>fascinating<\/em>.<\/p>\n<p>The value we&#8217;re really looking for here is <code>etag<\/code> (which really looks like <code>ETag<\/code> in the raw response).<\/p>\n<p>Bishop Fox (and others) figured out that that header value contains a timestamp in the last 8 characters. That timestamp maps to the release date of the particular PAN-OS version. Since Palo Alto maintains multiple, supported versions of PAN-OS and generally releases patches for them all at the same time, the mapping to an exact version is not super precise, but it&#8217;s sufficient to get an idea of whether that system is at a current, supported patch level.<\/p>\n<p>The last 8 characters of <code>7e0d5e2b6add<\/code> are <code>5e2b6add<\/code>, which \u2014 as Bishop Fox <a href=\"https:\/\/github.com\/noperator\/panos-scanner#description\">notes in their repo<\/a> \u2014 is just a hexadecimal encoding of the POSIX timestamp, in this case, <code>1579903709<\/code> or <code>2020-01-24 22:08:29 GMT<\/code> (we only care about the date, so really <code>2020-01-24<\/code>).<\/p>\n<p>We can compute that with R, but first we need to note that the value is surrounded by <code>\"<\/code> quotes, so we&#8217;ll have to deal with that during the processing:<\/p>\n<pre><code class=\"language-r\">httr::headers(res) %&gt;% \n  pluck(\"etag\") %&gt;% \n  gsub('\"', '', .) %&gt;% \n  substr(5, 12) %&gt;% \n  as.hexmode() %&gt;% \n  as.integer() %&gt;% \n  anytime::anytime(tz = \"GMT\") %&gt;% \n  as.Date() -&gt; version_date\n\nversion_date\n## [1] \"2020-01-24\"\n<\/code><\/pre>\n<p>To get the associated version(s), we need to look the date up in their <a href=\"https:\/\/raw.githubusercontent.com\/noperator\/panos-scanner\/master\/version-table.txt\">table<\/a>, which is in a fixed-width format that we can read via:<\/p>\n<pre><code class=\"language-r\">read_fwf(\n  file = \"https:\/\/raw.githubusercontent.com\/noperator\/panos-scanner\/master\/version-table.txt\",\n  col_positions = fwf_widths(c(10, 14), c(\"version\", \"date\")),\n  col_types = \"cc\",\n  trim_ws = TRUE\n) %&gt;% \n  mutate(\n    date = lubridate::mdy(date)\n  ) -&gt; panos_trans\n\npanos_trans\n## # A tibble: 153 x 2\n##    version  date      \n##    &lt;chr&gt;    &lt;date&gt;    \n##  1 6.0.0    2013-12-23\n##  2 6.0.1    2014-02-26\n##  3 6.0.2    2014-04-18\n##  4 6.0.3    2014-05-29\n##  5 6.0.4    2014-07-30\n##  6 6.0.5    2014-09-04\n##  7 6.0.5-h3 2014-10-07\n##  8 6.0.6    2014-10-07\n##  9 6.0.7    2014-11-18\n## 10 6.0.8    2015-01-13\n## # \u2026 with 143 more rows\n<\/code><\/pre>\n<p>Now, let&#8217;s see what version or versions this might be:<\/p>\n<pre><code class=\"language-r\">filter(panos_trans, date == version_date)\n## # A tibble: 2 x 2\n##   version date      \n##   &lt;chr&gt;   &lt;date&gt;    \n## 1 9.0.6   2020-01-24\n## 2 9.1.1   2020-01-24\n<\/code><\/pre>\n<h3>Putting It All Together<\/h3>\n<p>We can make a command line script for this (example) scanner:<\/p>\n<pre><code class=\"language-r\">#!env Rscript\nlibrary(purrr)\n\ngg &lt;- glue::glue\n\n# we also use {httr}, {readr}, {lubridate}, {anytime}, and {jsonlite}\n\nargs &lt;- commandArgs(trailingOnly = TRUE)\n\nstopifnot(\n  c(\n    \"Must supply both IP address and port\" = length(args) == 2\n  )\n)\n\nip &lt;- args[1]\nport &lt;-  args[2]\n\nhttr::HEAD(\n  url = gg(\"https:\/\/{ip}:{port}\/global-protect\/login.esp\"),\n  config = httr::config(\n    ssl_verifyhost =FALSE, \n    ssl_verifypeer = FALSE\n  )\n) -&gt; res\n\nhttr::headers(res) %&gt;% \n  pluck(\"etag\") %&gt;% \n  gsub('\"', '', .) %&gt;% \n  substr(5, 12) %&gt;% \n  as.hexmode() %&gt;% \n  as.integer() %&gt;% \n  anytime::anytime(tz = \"GMT\") %&gt;% \n  as.Date() -&gt; version_date\n\npanos_trans &lt;- readr::read_csv(\"panos-versions.txt\", col_types = \"cD\")\n\nres &lt;- panos_trans[panos_trans[[\"date\"]] == version_date,]\n\nif (nrow(res) == 0) {\n  cat(gg('{{\"ip\":\"{ip}\",\"port\":\"{port}\",\"version\"=null,\"date\"=null}}\\n'))\n} else {\n  res$ip &lt;- ip\n  res$port &lt;- port\n  jsonlite::stream_out(res[,c(\"ip\", \"port\", \"version\", \"date\")], verbose = FALSE)\n}\n<\/code><\/pre>\n<p>Save that as <code>panos-scanner.R<\/code> and make it executable (provided you&#8217;re on a non-legacy operating system that doesn&#8217;t support such modern capabilities). Save <code>panos_trans<\/code> as a CSV file in the same directory and try it against another (sanitized IP\/port) system:<\/p>\n<pre><code class=\"language-shell\">.\/panos-scanner.R 10.20.30.40 5678                                                                                                                                                    1\n{\"ip\":\"10.20.30.40\",\"port\":\"5678\",\"version\":\"9.1.2\",\"date\":\"2020-03-30\"}\n<\/code><\/pre>\n<h3>FIN<\/h3>\n<p>To be complete, the script should test all the URLs the ones in the script from Bishop Fox does and stand up many more guard rails to handle errors associated with unreachable hosts, getting headers from a system that is not a PAN-OS GP host, and ensuring the <code>ETag<\/code> is a valid date.<\/p>\n<p>You can grab the code [from this repo](https:\/\/git.rud.is\/hrbrmstr\/2020-07-10-panos-rstats.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The incredibly talented folks over at Bishop Fox were quite generous this week, providing a scanner for figuring out PAN-OS GlobalProtect versions. I&#8217;ve been using their decoding technique and date-based fingerprint table to keep an eye on patch status (over at $DAYJOB we help customers, organizations, and national cybersecurity centers get ahead of issues as [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"activitypub_content_warning":"","activitypub_content_visibility":"","activitypub_max_image_attachments":3,"activitypub_interaction_policy_quote":"anyone","activitypub_status":"","footnotes":""},"categories":[681,3,91],"tags":[],"class_list":["post-12790","post","type-post","status-publish","format-standard","hentry","category-cybersecurity","category-information-security","category-r"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>A Look at PAN-OS Versions with a Bit of R - rud.is<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/rud.is\/b\/2020\/07\/10\/a-look-at-pan-os-versions-with-a-bit-of-r\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"A Look at PAN-OS Versions with a Bit of R - rud.is\" \/>\n<meta property=\"og:description\" content=\"The incredibly talented folks over at Bishop Fox were quite generous this week, providing a scanner for figuring out PAN-OS GlobalProtect versions. I&#8217;ve been using their decoding technique and date-based fingerprint table to keep an eye on patch status (over at $DAYJOB we help customers, organizations, and national cybersecurity centers get ahead of issues as [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/rud.is\/b\/2020\/07\/10\/a-look-at-pan-os-versions-with-a-bit-of-r\/\" \/>\n<meta property=\"og:site_name\" content=\"rud.is\" \/>\n<meta property=\"article:published_time\" content=\"2020-07-10T16:03:51+00:00\" \/>\n<meta name=\"author\" content=\"hrbrmstr\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"hrbrmstr\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2020\\\/07\\\/10\\\/a-look-at-pan-os-versions-with-a-bit-of-r\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2020\\\/07\\\/10\\\/a-look-at-pan-os-versions-with-a-bit-of-r\\\/\"},\"author\":{\"name\":\"hrbrmstr\",\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/#\\\/schema\\\/person\\\/d7cb7487ab0527447f7fda5c423ff886\"},\"headline\":\"A Look at PAN-OS Versions with a Bit of R\",\"datePublished\":\"2020-07-10T16:03:51+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2020\\\/07\\\/10\\\/a-look-at-pan-os-versions-with-a-bit-of-r\\\/\"},\"wordCount\":939,\"commentCount\":2,\"publisher\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/#\\\/schema\\\/person\\\/d7cb7487ab0527447f7fda5c423ff886\"},\"articleSection\":[\"Cybersecurity\",\"Information Security\",\"R\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/rud.is\\\/b\\\/2020\\\/07\\\/10\\\/a-look-at-pan-os-versions-with-a-bit-of-r\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2020\\\/07\\\/10\\\/a-look-at-pan-os-versions-with-a-bit-of-r\\\/\",\"url\":\"https:\\\/\\\/rud.is\\\/b\\\/2020\\\/07\\\/10\\\/a-look-at-pan-os-versions-with-a-bit-of-r\\\/\",\"name\":\"A Look at PAN-OS Versions with a Bit of R - rud.is\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/#website\"},\"datePublished\":\"2020-07-10T16:03:51+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2020\\\/07\\\/10\\\/a-look-at-pan-os-versions-with-a-bit-of-r\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/rud.is\\\/b\\\/2020\\\/07\\\/10\\\/a-look-at-pan-os-versions-with-a-bit-of-r\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2020\\\/07\\\/10\\\/a-look-at-pan-os-versions-with-a-bit-of-r\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/rud.is\\\/b\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"A Look at PAN-OS Versions with a Bit of R\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/#website\",\"url\":\"https:\\\/\\\/rud.is\\\/b\\\/\",\"name\":\"rud.is\",\"description\":\"&quot;In God we trust. All others must bring data&quot;\",\"publisher\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/#\\\/schema\\\/person\\\/d7cb7487ab0527447f7fda5c423ff886\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/rud.is\\\/b\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/#\\\/schema\\\/person\\\/d7cb7487ab0527447f7fda5c423ff886\",\"name\":\"hrbrmstr\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/i0.wp.com\\\/rud.is\\\/b\\\/wp-content\\\/uploads\\\/2023\\\/10\\\/ukr-shield.png?fit=460%2C460&ssl=1\",\"url\":\"https:\\\/\\\/i0.wp.com\\\/rud.is\\\/b\\\/wp-content\\\/uploads\\\/2023\\\/10\\\/ukr-shield.png?fit=460%2C460&ssl=1\",\"contentUrl\":\"https:\\\/\\\/i0.wp.com\\\/rud.is\\\/b\\\/wp-content\\\/uploads\\\/2023\\\/10\\\/ukr-shield.png?fit=460%2C460&ssl=1\",\"width\":460,\"height\":460,\"caption\":\"hrbrmstr\"},\"logo\":{\"@id\":\"https:\\\/\\\/i0.wp.com\\\/rud.is\\\/b\\\/wp-content\\\/uploads\\\/2023\\\/10\\\/ukr-shield.png?fit=460%2C460&ssl=1\"},\"description\":\"Don't look at me\u2026I do what he does \u2014 just slower. #rstats avuncular \u2022 ?Resistance Fighter \u2022 Cook \u2022 Christian \u2022 [Master] Chef des Donn\u00e9es de S\u00e9curit\u00e9 @ @rapid7\",\"sameAs\":[\"http:\\\/\\\/rud.is\"],\"url\":\"https:\\\/\\\/rud.is\\\/b\\\/author\\\/hrbrmstr\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"A Look at PAN-OS Versions with a Bit of R - rud.is","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/rud.is\/b\/2020\/07\/10\/a-look-at-pan-os-versions-with-a-bit-of-r\/","og_locale":"en_US","og_type":"article","og_title":"A Look at PAN-OS Versions with a Bit of R - rud.is","og_description":"The incredibly talented folks over at Bishop Fox were quite generous this week, providing a scanner for figuring out PAN-OS GlobalProtect versions. I&#8217;ve been using their decoding technique and date-based fingerprint table to keep an eye on patch status (over at $DAYJOB we help customers, organizations, and national cybersecurity centers get ahead of issues as [&hellip;]","og_url":"https:\/\/rud.is\/b\/2020\/07\/10\/a-look-at-pan-os-versions-with-a-bit-of-r\/","og_site_name":"rud.is","article_published_time":"2020-07-10T16:03:51+00:00","author":"hrbrmstr","twitter_card":"summary_large_image","twitter_misc":{"Written by":"hrbrmstr","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/rud.is\/b\/2020\/07\/10\/a-look-at-pan-os-versions-with-a-bit-of-r\/#article","isPartOf":{"@id":"https:\/\/rud.is\/b\/2020\/07\/10\/a-look-at-pan-os-versions-with-a-bit-of-r\/"},"author":{"name":"hrbrmstr","@id":"https:\/\/rud.is\/b\/#\/schema\/person\/d7cb7487ab0527447f7fda5c423ff886"},"headline":"A Look at PAN-OS Versions with a Bit of R","datePublished":"2020-07-10T16:03:51+00:00","mainEntityOfPage":{"@id":"https:\/\/rud.is\/b\/2020\/07\/10\/a-look-at-pan-os-versions-with-a-bit-of-r\/"},"wordCount":939,"commentCount":2,"publisher":{"@id":"https:\/\/rud.is\/b\/#\/schema\/person\/d7cb7487ab0527447f7fda5c423ff886"},"articleSection":["Cybersecurity","Information Security","R"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/rud.is\/b\/2020\/07\/10\/a-look-at-pan-os-versions-with-a-bit-of-r\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/rud.is\/b\/2020\/07\/10\/a-look-at-pan-os-versions-with-a-bit-of-r\/","url":"https:\/\/rud.is\/b\/2020\/07\/10\/a-look-at-pan-os-versions-with-a-bit-of-r\/","name":"A Look at PAN-OS Versions with a Bit of R - rud.is","isPartOf":{"@id":"https:\/\/rud.is\/b\/#website"},"datePublished":"2020-07-10T16:03:51+00:00","breadcrumb":{"@id":"https:\/\/rud.is\/b\/2020\/07\/10\/a-look-at-pan-os-versions-with-a-bit-of-r\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/rud.is\/b\/2020\/07\/10\/a-look-at-pan-os-versions-with-a-bit-of-r\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/rud.is\/b\/2020\/07\/10\/a-look-at-pan-os-versions-with-a-bit-of-r\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/rud.is\/b\/"},{"@type":"ListItem","position":2,"name":"A Look at PAN-OS Versions with a Bit of R"}]},{"@type":"WebSite","@id":"https:\/\/rud.is\/b\/#website","url":"https:\/\/rud.is\/b\/","name":"rud.is","description":"&quot;In God we trust. All others must bring data&quot;","publisher":{"@id":"https:\/\/rud.is\/b\/#\/schema\/person\/d7cb7487ab0527447f7fda5c423ff886"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/rud.is\/b\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/rud.is\/b\/#\/schema\/person\/d7cb7487ab0527447f7fda5c423ff886","name":"hrbrmstr","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/10\/ukr-shield.png?fit=460%2C460&ssl=1","url":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/10\/ukr-shield.png?fit=460%2C460&ssl=1","contentUrl":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/10\/ukr-shield.png?fit=460%2C460&ssl=1","width":460,"height":460,"caption":"hrbrmstr"},"logo":{"@id":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/10\/ukr-shield.png?fit=460%2C460&ssl=1"},"description":"Don't look at me\u2026I do what he does \u2014 just slower. #rstats avuncular \u2022 ?Resistance Fighter \u2022 Cook \u2022 Christian \u2022 [Master] Chef des Donn\u00e9es de S\u00e9curit\u00e9 @ @rapid7","sameAs":["http:\/\/rud.is"],"url":"https:\/\/rud.is\/b\/author\/hrbrmstr\/"}]}},"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p23idr-3ki","jetpack_likes_enabled":true,"jetpack-related-posts":[{"id":12094,"url":"https:\/\/rud.is\/b\/2019\/03\/17\/handling-sharing-pcaps-like-a-boss-with-packettotal\/","url_meta":{"origin":12790,"position":0},"title":"Handling &#038; Sharing PCAPs Like a Boss with PacketTotal","author":"hrbrmstr","date":"2019-03-17","format":false,"excerpt":"The fine folks over at @PacketTotal bequeathed an API token on me so I cranked out an R package for it to enable more dynamic investigations work (RStudio makes for an amazing incident responder investigations console given that you can script in multiple languages, code in C[++], and write documentation\u2026","rel":"","context":"In &quot;Cybersecurity&quot;","block_context":{"text":"Cybersecurity","link":"https:\/\/rud.is\/b\/category\/cybersecurity\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":3887,"url":"https:\/\/rud.is\/b\/2016\/01\/09\/the-force-accounted-in-r\/","url_meta":{"origin":12790,"position":1},"title":"The Force: Accounted, in R","author":"hrbrmstr","date":"2016-01-09","format":false,"excerpt":"Despite being a cybersecurity professional, it's pretty easy to social engineer me: https:\/\/t.co\/R3qVHEMTLo @hrbrmstr is there an R package? ;)\u2014 Thorsten G. (@SaThaRiel74) January 8, 2016 I'll note that @jayjacobs does it all the time to me. I took Thorsten's tweet as a challenge to ggplot2-ize the Bloomberg visualizations as\u2026","rel":"","context":"In &quot;Data Visualization&quot;","block_context":{"text":"Data Visualization","link":"https:\/\/rud.is\/b\/category\/data-visualization\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2016\/01\/CYSe8-BWkAASc1l.png?fit=600%2C447&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2016\/01\/CYSe8-BWkAASc1l.png?fit=600%2C447&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2016\/01\/CYSe8-BWkAASc1l.png?fit=600%2C447&ssl=1&resize=525%2C300 1.5x"},"classes":[]},{"id":3770,"url":"https:\/\/rud.is\/b\/2015\/11\/02\/an-ephemeral-update-to-daylight\/","url_meta":{"origin":12790,"position":2},"title":"An Ephemeral Update to daylight()","author":"hrbrmstr","date":"2015-11-02","format":false,"excerpt":"This occurrence of the bi-annual corruption of the space-time continuum (i.e. changing to\/from standard\/daylight time) in the U.S. caused me to make a slight change to the code [from an older post](https:\/\/rud.is\/b\/2014\/09\/23\/seeing-the-daylight-with-r\/). The `daylight()` function now auto-discovers the date and location information (via [telize](http:\/\/www.telize.com\/)) from the caller, which means all\u2026","rel":"","context":"In &quot;Charts &amp; Graphs&quot;","block_context":{"text":"Charts &amp; Graphs","link":"https:\/\/rud.is\/b\/category\/charts-graphs\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2015\/11\/RStudio.png?fit=1200%2C1088&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2015\/11\/RStudio.png?fit=1200%2C1088&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2015\/11\/RStudio.png?fit=1200%2C1088&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2015\/11\/RStudio.png?fit=1200%2C1088&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2015\/11\/RStudio.png?fit=1200%2C1088&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":3775,"url":"https:\/\/rud.is\/b\/2015\/11\/08\/visualizing_survey_data\/","url_meta":{"origin":12790,"position":3},"title":"Visualizing Survey Data : Comparison Between Observations","author":"hrbrmstr","date":"2015-11-08","format":false,"excerpt":"Cybersecurity is a domain that really likes surveys, or at the very least it has many folks within it that like to conduct and report on surveys. One recent survey on threat intelligence is in it's second year, so it sets about comparing answers across years. Rather than go into\u2026","rel":"","context":"In &quot;Cybersecurity&quot;","block_context":{"text":"Cybersecurity","link":"https:\/\/rud.is\/b\/category\/cybersecurity\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2015\/11\/Visualizing_Survey_Data___Comparison_Between_Observations.png?fit=1200%2C721&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2015\/11\/Visualizing_Survey_Data___Comparison_Between_Observations.png?fit=1200%2C721&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2015\/11\/Visualizing_Survey_Data___Comparison_Between_Observations.png?fit=1200%2C721&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2015\/11\/Visualizing_Survey_Data___Comparison_Between_Observations.png?fit=1200%2C721&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2015\/11\/Visualizing_Survey_Data___Comparison_Between_Observations.png?fit=1200%2C721&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":3871,"url":"https:\/\/rud.is\/b\/2016\/01\/07\/paths-to-discovery-how-to-keep-tabs-on-your-home-network\/","url_meta":{"origin":12790,"position":4},"title":"Paths To Discovery: Mapping Your Home Network","author":"hrbrmstr","date":"2016-01-07","format":false,"excerpt":"Gone are the days when one had a single computer plugged directly into a modem (cable, DSL or good ol' Hayes). Even the days when there were just one or two computers connected via wires or invisible multi-gigahertz waves passing through the air are in the long gone by. Today\u2026","rel":"","context":"In &quot;Cybersecurity&quot;","block_context":{"text":"Cybersecurity","link":"https:\/\/rud.is\/b\/category\/cybersecurity\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2016\/01\/maxresdefault.jpg?fit=1200%2C675&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2016\/01\/maxresdefault.jpg?fit=1200%2C675&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2016\/01\/maxresdefault.jpg?fit=1200%2C675&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2016\/01\/maxresdefault.jpg?fit=1200%2C675&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2016\/01\/maxresdefault.jpg?fit=1200%2C675&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":7924,"url":"https:\/\/rud.is\/b\/2018\/01\/18\/bitcoin-world-map-bubbles\/","url_meta":{"origin":12790,"position":5},"title":"Bitcoin (World Map) Bubbles","author":"hrbrmstr","date":"2018-01-18","format":false,"excerpt":"We're doing some interesting studies (cybersecurity-wise, not finance-wise) on digital currency networks at work-work and --- while I'm loathe to create a geo-map from IPv4 geolocation data --- we: do get (often, woefully inaccurate) latitude & longitude data from our geolocation service (I won't name-and-shame here); and, there are definite\u2026","rel":"","context":"In &quot;R&quot;","block_context":{"text":"R","link":"https:\/\/rud.is\/b\/category\/r\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2018\/01\/map-1.png?fit=1200%2C960&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2018\/01\/map-1.png?fit=1200%2C960&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2018\/01\/map-1.png?fit=1200%2C960&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2018\/01\/map-1.png?fit=1200%2C960&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2018\/01\/map-1.png?fit=1200%2C960&ssl=1&resize=1050%2C600 3x"},"classes":[]}],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/posts\/12790","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/comments?post=12790"}],"version-history":[{"count":0,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/posts\/12790\/revisions"}],"wp:attachment":[{"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/media?parent=12790"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/categories?post=12790"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/tags?post=12790"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}