{"id":1348,"date":"2024-10-25T15:29:05","date_gmt":"2024-10-25T19:29:05","guid":{"rendered":"https:\/\/studentorgs.syr.edu\/isc\/?p=1348"},"modified":"2024-10-25T15:32:51","modified_gmt":"2024-10-25T19:32:51","slug":"reverse-engineering-walkthrough-10-1-meeting","status":"publish","type":"post","link":"https:\/\/studentorgs.syr.edu\/isc\/2024\/10\/25\/reverse-engineering-walkthrough-10-1-meeting\/","title":{"rendered":"Reverse Engineering Walkthrough &#8211; 10\/1 Meeting"},"content":{"rendered":"<div class=\"markdown-heading\" dir=\"auto\">\n<h1 class=\"heading-element\" dir=\"auto\">ISC_Crackme Walkthrough<\/h1>\n<p>By Townsend Southard Pantano<\/p>\n<p><a href=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/blob\/master\/walkthrough\/Walkthrough.md\">Github<\/a><\/p>\n<p><span style=\"font-size: 1.25rem\">This simple license validator is designed to expose the user to a revere engineering workflow, using Binary Ninja to reverse the license format and validation to bypass the license check and generate a license that the program thinks is valid.<\/span><\/p>\n<\/div>\n<div class=\"markdown-heading\" dir=\"auto\">\n<h3 class=\"heading-element\" dir=\"auto\">The goal:<\/h3>\n<h3 class=\"heading-element\" dir=\"auto\"><span style=\"font-size: 1.25rem\">Generate your own license that will be accepted by the program. Your license should result in valid values for all the fields under<\/span><span style=\"font-size: 1.25rem\">\u00a0<\/span><code>License Details<\/code><span style=\"font-size: 1.25rem\">:<\/span><\/h3>\n<\/div>\n<p dir=\"auto\"><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/blob\/master\/walkthrough\/imgs\/successful_demo.png\"><img decoding=\"async\" src=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/raw\/master\/walkthrough\/imgs\/successful_demo.png\" alt=\"successful_demo.png\" \/><\/a><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/blob\/master\/walkthrough\/imgs\/licenseDemo.png\"><img decoding=\"async\" src=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/raw\/master\/walkthrough\/imgs\/licenseDemo.png\" alt=\"img.png\" \/><\/a><\/p>\n<div class=\"markdown-heading\" dir=\"auto\">\n<h3 class=\"heading-element\" dir=\"auto\">Running the program:<\/h3>\n<h3 class=\"heading-element\" dir=\"auto\"><span style=\"font-size: 1.25rem\">When the program starts, you should see a UI that looks similar to this:<\/span><\/h3>\n<\/div>\n<p dir=\"auto\"><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/blob\/master\/walkthrough\/imgs\/img.png\"><img decoding=\"async\" src=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/raw\/master\/walkthrough\/imgs\/img.png\" alt=\"img.png\" \/><\/a><\/p>\n<p dir=\"auto\">Pressing &#8220;Check License&#8221; yields an error message,<span>\u00a0<\/span><code>Invalid number of fields - The license needs more information<\/code>. While not the most useful, that error message lets us know that the license contains several fields, each with some sort of information.<\/p>\n<div class=\"markdown-heading\" dir=\"auto\">\n<h3 class=\"heading-element\" dir=\"auto\">Loading in Binary Ninja:<\/h3>\n<h3 class=\"heading-element\" dir=\"auto\"><span style=\"font-size: 1.25rem\"><\/span><a href=\"https:\/\/binary.ninja\/\" rel=\"nofollow\" style=\"font-size: 1.25rem;background-color: #f7f7f8\">Binary Ninja<\/a><span style=\"font-size: 1.25rem\">\u00a0<\/span><span style=\"font-size: 1.25rem\">is a reverse engineering platform that allows us to disassemble and analyze the program. We will use it to reverse engineer the license format and validation to generate a valid license. After loading the program into Binja, set the view mode to &#8220;Pseudo C&#8221; at the top of the disassembly view to make the disassembly easier to read. The function names can be seen in the left top panel, under &#8220;Symbols&#8221;, and the strings can be found by clicking on the double-quote icon in the column to the right of the disassembly view.<\/span><\/h3>\n<\/div>\n<blockquote>\n<p dir=\"auto\">Note: Details in the screenshots will be different on different builds of the program. The view in the screenshots is the Linux build of the program<\/p>\n<\/blockquote>\n<div class=\"markdown-heading\" dir=\"auto\">\n<h4 class=\"heading-element\" dir=\"auto\">Strings: The low-hanging fruit<\/h4>\n<h4 class=\"heading-element\" dir=\"auto\"><span style=\"font-size: 1.25rem\">We can search the strings panel for the error message we saw earlier,<\/span><span style=\"font-size: 1.25rem\">\u00a0<\/span><code>Invalid number of fields - The license needs more information<\/code><span style=\"font-size: 1.25rem\">, to try and find the function that causes it.<\/span><\/h4>\n<\/div>\n<p dir=\"auto\">There will be one result, and double-clicking on it will take us to the strings table. While not the validation function that we were hoping for, the strings table is just as useful.<\/p>\n<p dir=\"auto\"><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/blob\/master\/walkthrough\/imgs\/stringtable.png\"><img decoding=\"async\" src=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/raw\/master\/walkthrough\/imgs\/stringtable.png\" alt=\"img_1.png\" \/><\/a><\/p>\n<p dir=\"auto\">The strings table is mostly in order, and the possible error messages are towards the bottom of the screenshot: Here are the error messages:<\/p>\n<ul dir=\"auto\">\n<li><code>License Successfully Verified!<\/code><\/li>\n<li><code>Invalid format<\/code><\/li>\n<li><code>Invalid number of fields - The license needs more information<\/code><\/li>\n<li><code>Invalid secret number<\/code><\/li>\n<li><code>Invalid licensee email address<\/code><\/li>\n<li><code>License hasn't begun yet<\/code><\/li>\n<li><code>License expired<\/code><\/li>\n<li><code>Invalid license dates. Time travel is prohibited<\/code><\/li>\n<li><code>Invalid license type<\/code><\/li>\n<li><code>Unknown error<\/code><\/li>\n<\/ul>\n<p dir=\"auto\">The error messages let us know the following about the format of the license:<\/p>\n<ul dir=\"auto\">\n<li>A secret number is required<\/li>\n<li>An email address is required<\/li>\n<li>The license has a start date<\/li>\n<li>The license has an expiration date<\/li>\n<li>The license has a type<\/li>\n<li>The license is looking for a specific format<\/li>\n<\/ul>\n<p dir=\"auto\">Therefore, we can assume that the license has 5 fields:<\/p>\n<ol dir=\"auto\">\n<li>Secret number<\/li>\n<li>Email address<\/li>\n<li>Start date<\/li>\n<li>Expiration date<\/li>\n<li>License type<\/li>\n<\/ol>\n<div class=\"markdown-heading\" dir=\"auto\">\n<h4 class=\"heading-element\" dir=\"auto\"><strong>Setting types<\/strong><\/h4>\n<h4 class=\"heading-element\" dir=\"auto\"><span style=\"font-size: 1.25rem\">While in the string table, I will set the format of<\/span><span style=\"font-size: 1.25rem\">\u00a0<\/span><code>data_43cdfd<\/code><span style=\"font-size: 1.25rem\">\u00a0<\/span><span style=\"font-size: 1.25rem\">to C string. Because the &#8216;0x2C&#8217; byte is in the string table, it is most likely a C string.<\/span><span style=\"font-size: 1.25rem\">\u00a0<\/span><\/h4>\n<\/div>\n<p dir=\"auto\"><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/blob\/master\/walkthrough\/imgs\/makingCString.png\"><img decoding=\"async\" src=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/raw\/master\/walkthrough\/imgs\/makingCString.png\" alt=\"img_1.png\" \/><\/a><\/p>\n<p dir=\"auto\">After the type has been set to a C string, we can see that the string is a comma.<span>\u00a0<\/span><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/blob\/master\/walkthrough\/imgs\/is_comma.png\"><img decoding=\"async\" src=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/raw\/master\/walkthrough\/imgs\/is_comma.png\" alt=\"img_1.png\" \/><\/a><\/p>\n<div class=\"markdown-heading\" dir=\"auto\">\n<h4 class=\"heading-element\" dir=\"auto\"><strong>Reading Regular Expressions<\/strong><\/h4>\n<h4 class=\"heading-element\" dir=\"auto\"><span style=\"font-size: 1.25rem\">Also in the string table are 2 regular expressions,<\/span><span style=\"font-size: 1.25rem\">\u00a0<\/span><\/h4>\n<\/div>\n<p dir=\"auto\"><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/blob\/master\/walkthrough\/imgs\/b64regex.png\"><img decoding=\"async\" src=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/raw\/master\/walkthrough\/imgs\/b64regex.png\" alt=\"img_2.png\" \/><\/a><\/p>\n<p dir=\"auto\"><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/blob\/master\/walkthrough\/imgs\/emailregex.png\"><img decoding=\"async\" src=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/raw\/master\/walkthrough\/imgs\/emailregex.png\" alt=\"img_1.png\" \/><\/a><\/p>\n<p dir=\"auto\">The first regex will match any string composed of blocks of 4 Alphanumeric characters, terminated by either 2 or 1<span>\u00a0<\/span><code>=<\/code><span>\u00a0<\/span>characters. This is the format of a base64 string, so it can be renamed &#8220;base64regex&#8221; by right-clicking on the data block name and selecting &#8220;Rename&#8221;.<\/p>\n<blockquote>\n<p dir=\"auto\">Note: Base64 encoding is a common method of encoding data as text, using the characters A-Z, a-z, 0-9, and the symbols<span>\u00a0<\/span><code>+<\/code><span>\u00a0<\/span>and<span>\u00a0<\/span><code>\/<\/code>. The<span>\u00a0<\/span><code>=<\/code><span>\u00a0<\/span>character is used as padding at the end of the string. It is particularly useful when a programmer needs to encode non-printable data as printable text.<\/p>\n<\/blockquote>\n<p dir=\"auto\">Regex #2 sill match any string consisting of a series of alphanumeric characters, followed by an<span>\u00a0<\/span><code>@<\/code><span>\u00a0<\/span>symbol, followed by another series of alphanumeric characters, and ending with a<span>\u00a0<\/span><code>.<\/code><span>\u00a0<\/span>followed by another series of alphanumeric characters. Therefore, this regex is likely meant to match any email addresses, and can be renamed as such.<\/p>\n<p dir=\"auto\">At this point, the string table should look like this:<span>\u00a0<\/span><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/blob\/master\/walkthrough\/imgs\/img_1.png\"><img decoding=\"async\" src=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/raw\/master\/walkthrough\/imgs\/img_1.png\" alt=\"img_1.png\" \/><\/a><\/p>\n<div class=\"markdown-heading\" dir=\"auto\">\n<h3 class=\"heading-element\" dir=\"auto\">Finding the format-checking function<\/h3>\n<h3 class=\"heading-element\" dir=\"auto\"><span style=\"font-size: 1.25rem\">We can search for likely function names that may be called to validate the license. While function names will often be stripped from compiled programs, they are available in this example.<\/span><\/h3>\n<\/div>\n<p dir=\"auto\">By searching &#8216;license&#8217; in the Symbols panel, we will have a list of matching functions:<span>\u00a0<\/span><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/blob\/master\/walkthrough\/imgs\/searching.png\"><img decoding=\"async\" src=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/raw\/master\/walkthrough\/imgs\/searching.png\" alt=\"img.png\" \/><\/a><\/p>\n<p dir=\"auto\">We can look at the function<span>\u00a0<\/span><code>License::checkFormat(std::string)<\/code><span>\u00a0<\/span>by double-clicking the function name in the symbols list.<\/p>\n<p dir=\"auto\">Near the top of the function, we can see that it calls<span>\u00a0<\/span><code>License::b64Check(std::string)<\/code>, then xors the result with 1. Therefore, if the base64 check succeeds, then the variable will be set to 0. I will rename this variable to<span>\u00a0<\/span><code>b64CheckResult<\/code><span>\u00a0<\/span>for clarity. Also, arg2 should be renamed to &#8216;inputString&#8217;.<\/p>\n<p dir=\"auto\">The<span>\u00a0<\/span><code>License::checkFormat(std::string)<\/code><span>\u00a0<\/span>function should look like this now:<span>\u00a0<\/span><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/blob\/master\/walkthrough\/imgs\/renamedVariables.png\"><img decoding=\"async\" src=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/raw\/master\/walkthrough\/imgs\/renamedVariables.png\" alt=\"img.png\" \/><\/a><\/p>\n<div class=\"markdown-heading\" dir=\"auto\">\n<h3 class=\"heading-element\" dir=\"auto\">Base64 Check<\/h3>\n<h3 class=\"heading-element\" dir=\"auto\"><span style=\"font-size: 1.25rem\">We can look at<\/span><span style=\"font-size: 1.25rem\">\u00a0<\/span><code>License::b64Check(std::string)<\/code><span style=\"font-size: 1.25rem\">\u00a0<\/span><span style=\"font-size: 1.25rem\">by double-clicking the function name in the symbols list.<\/span><\/h3>\n<\/div>\n<p dir=\"auto\"><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/blob\/master\/walkthrough\/imgs\/b64check.png\"><img decoding=\"async\" src=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/raw\/master\/walkthrough\/imgs\/b64check.png\" alt=\"img.png\" \/><\/a><\/p>\n<p dir=\"auto\">While there is some logic in the function, near the bottom we can see that it is checking if a string matches a regular expression. We can select the regular expression,<span>\u00a0<\/span><code>\"^([A-Za-z0-9+\/]{4})*([A-Za-z0-9+\u2026<\/code><span>\u00a0<\/span>and look at the<span>\u00a0<\/span><code>Cross References<\/code><span>\u00a0<\/span>(xrefs) pane in the bottom left to see where it is defined. Looking at the xrefs panel, we can see that the regex is the string we renamed to<span>\u00a0<\/span><code>base64regex<\/code><span>\u00a0<\/span>earlier. Now we know for a fact that this function is checking if a string is a base64 string.<\/p>\n<div class=\"markdown-heading\" dir=\"auto\">\n<h3 class=\"heading-element\" dir=\"auto\">Back to<span>\u00a0<\/span><code>License::checkFormat(std::string)<\/code><\/h3>\n<h3 class=\"heading-element\" dir=\"auto\"><code><\/code><span style=\"font-size: 1.25rem\">Returning to<\/span><span style=\"font-size: 1.25rem\">\u00a0<\/span><code>License::checkFormat(std::string)<\/code><span style=\"font-size: 1.25rem\">, we can see that the function enters an if statement<\/span><span style=\"font-size: 1.25rem\">\u00a0<\/span><code>if (b64CheckResult == 0)<\/code><span style=\"font-size: 1.25rem\">, which we know means that the base64 check succeeded.<\/span><\/h3>\n<\/div>\n<p dir=\"auto\">The first code executed inside the if statement is:<\/p>\n<div class=\"snippet-clipboard-content notranslate position-relative overflow-auto\">\n<pre class=\"notranslate\"><code>0040ab27          void var_c8;\r\n0040ab27          b64_decode(&amp;var_c8, inputString);\r\n<\/code><\/pre>\n<div><\/div>\n<div class=\"zeroclipboard-container\"><span style=\"font-size: 1.25rem\">This snippet base64 decodes<\/span><span style=\"font-size: 1.25rem\">\u00a0<\/span><code>inputString<\/code><span style=\"font-size: 1.25rem\">\u00a0<\/span><span style=\"font-size: 1.25rem\">and stores the result in<\/span><span style=\"font-size: 1.25rem\">\u00a0<\/span><code>var_c8<\/code><span style=\"font-size: 1.25rem\">, which will be renamed to<\/span><span style=\"font-size: 1.25rem\">\u00a0<\/span><code>decodedString<\/code><span style=\"font-size: 1.25rem\">.<\/span><\/div>\n<div><\/div>\n<\/div>\n<blockquote>\n<p dir=\"auto\">Note: the structure of assigning a variable of void type and immediately calling a function with that as the argument is a common way of passing a reference to a variable. The called function will then set its result to that variable passed in.<\/p>\n<\/blockquote>\n<p dir=\"auto\">Scrolling down towards the bottom of the function to find the next usage of<span>\u00a0<\/span><code>decodedString<\/code>, we can see that it is passed to a function<span>\u00a0<\/span><code>splitString<\/code><span>\u00a0<\/span><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/blob\/master\/walkthrough\/imgs\/callingSplitString.png\"><img decoding=\"async\" src=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/raw\/master\/walkthrough\/imgs\/callingSplitString.png\" alt=\"img.png\" \/><\/a><\/p>\n<p dir=\"auto\">We can see that<span>\u00a0<\/span><code>splitString<\/code><span>\u00a0<\/span>is called with<span>\u00a0<\/span><code>decodedString<\/code>, a new variable, and<span>\u00a0<\/span><code>0x2C<\/code><span>\u00a0<\/span>as arguments. We can make this clearer by renaming the first argument, in my case<span>\u00a0<\/span><code>var_108<\/code>, to<span>\u00a0<\/span><code>splitString<\/code>, and by setting the display mode of the<span>\u00a0<\/span><code>0x2c<\/code><span>\u00a0<\/span>to be a character constant, as is shown below:<\/p>\n<p dir=\"auto\"><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/blob\/master\/walkthrough\/imgs\/splitStringAnalysis.png\"><img decoding=\"async\" src=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/raw\/master\/walkthrough\/imgs\/splitStringAnalysis.png\" alt=\"img.png\" \/><\/a><\/p>\n<p dir=\"auto\">After changing the display mode, we can see that the function is calling splitString with the decoded string and a comma as arguments.<\/p>\n<p dir=\"auto\">We can now see that the split output is used right underneath the call to<span>\u00a0<\/span><code>splitString<\/code><span>\u00a0<\/span>by checking to see if number of strings in the output is not 5.<span>\u00a0<\/span><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/blob\/master\/walkthrough\/imgs\/lengthcheck.png\"><img decoding=\"async\" src=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/raw\/master\/walkthrough\/imgs\/lengthcheck.png\" alt=\"img.png\" \/><\/a><span>\u00a0<\/span>In the screenshot, the variable rax_8 will be 1 if the length of the list<span>\u00a0<\/span><code>splitStringOutput<\/code><span>\u00a0<\/span>is not 5, and 0 if the length is 5.<\/p>\n<p dir=\"auto\"><strong>Therefore, we can be sure that there are 5 fields in our valid license<\/strong><\/p>\n<p dir=\"auto\">If the length check succeeds (if rax_8 is 0), the function will execute a regular expression check on the first element of the split string:<\/p>\n<div class=\"highlight highlight-source-c notranslate position-relative overflow-auto\" dir=\"auto\">\n<pre><span class=\"pl-k\">if<\/span> (<span class=\"pl-s1\">rax_8<\/span> <span class=\"pl-c1\">==<\/span> <span class=\"pl-c1\">0<\/span>)\r\n{\r\n    <span class=\"pl-smi\">void<\/span> <span class=\"pl-s1\">var_128<\/span>;\r\n    std::<span class=\"pl-s1\">basic_regex<\/span><span class=\"pl-c1\">&lt;<\/span><span class=\"pl-s1\">char<\/span>, <span class=\"pl-s1\">std<\/span>::<span class=\"pl-s1\">regex_traits<\/span><span class=\"pl-c1\">&lt;<\/span><span class=\"pl-s1\">char<\/span><span class=\"pl-c1\">&gt;<\/span> <span class=\"pl-c1\">&gt;<\/span>::<span class=\"pl-en\">basic_regex<\/span>(<span class=\"pl-c1\">&amp;<\/span><span class=\"pl-s1\">var_128<\/span>, <span class=\"pl-s\">\"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]\u2026\"<\/span>, <span class=\"pl-c1\">0x10<\/span>);\r\n    \r\n    <span class=\"pl-k\">if<\/span> (<span class=\"pl-s1\">std<\/span>::<span class=\"pl-s1\">regex_match<\/span><span class=\"pl-c1\">&lt;<\/span><span class=\"pl-s1\">std<\/span>::<span class=\"pl-s1\">ch<\/span>...<span class=\"pl-c1\">har<\/span><span class=\"pl-c1\">&gt;<\/span><span class=\"pl-s1\"><\/span>, <span class=\"pl-s1\">char<\/span>, <span class=\"pl-s1\">std<\/span>::<span class=\"pl-s1\">regex_traits<\/span><span class=\"pl-c1\">&lt;<\/span><span class=\"pl-s1\">char<\/span><span class=\"pl-c1\">&gt;<\/span><span class=\"pl-s1\"><\/span> <span class=\"pl-c1\">&gt;<\/span>(<span class=\"pl-s1\">std<\/span>::<span class=\"pl-s1\">vector<\/span><span class=\"pl-c1\">&lt;<\/span><span class=\"pl-s1\">std<\/span>::<span class=\"pl-s1\">string<\/span><span class=\"pl-c1\">&gt;<\/span>::<span class=\"pl-s1\">operator<\/span>[<span class=\"pl-s1\"><\/span>](<span class=\"pl-c1\">&amp;<\/span><span class=\"pl-s1\">splitStringOutput<\/span>, <span class=\"pl-c1\">0<\/span>), <span class=\"pl-c1\">&amp;<\/span><span class=\"pl-s1\">var_128<\/span>, <span class=\"pl-c1\">0<\/span>) <span class=\"pl-c1\">==<\/span> <span class=\"pl-c1\">1<\/span>)\r\n        <span class=\"pl-s1\">rbx_1<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-c1\">0<\/span>;\r\n    <span class=\"pl-k\">else<\/span>\r\n        <span class=\"pl-s1\">rbx_1<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-c1\">4<\/span>;\r\n    \r\n    std::<span class=\"pl-s1\">basic_regex<\/span><span class=\"pl-c1\">&lt;<\/span><span class=\"pl-s1\">char<\/span>, <span class=\"pl-s1\">std<\/span>::<span class=\"pl-s1\">regex_traits<\/span><span class=\"pl-c1\">&lt;<\/span><span class=\"pl-s1\">char<\/span><span class=\"pl-c1\">&gt;<\/span> <span class=\"pl-c1\">&gt;<\/span>::~<span class=\"pl-en\">basic_regex<\/span>(<span class=\"pl-c1\">&amp;<\/span><span class=\"pl-s1\">var_128<\/span>);\r\n}<\/pre>\n<\/div>\n<p dir=\"auto\">While it looks complex, it can be simplified relatively easily. Lines 0040ac60 are creating a regex object that checks if a string has an @ symbol, then saves that to<span>\u00a0<\/span><code>var_128<\/code><span>\u00a0<\/span>Lines 0040ac98 are checking if the first element of the split string matches the regex<\/p>\n<blockquote>\n<p dir=\"auto\">Note:<span>\u00a0<\/span><code>std::vector&lt;std::string&gt;::operator[](&amp;splitStringOutput, 0)<\/code><span>\u00a0<\/span>is the same as calling<span>\u00a0<\/span><code>splitStringOutput[0]<\/code><span>\u00a0<\/span>&#8211; both are accessing the first element of the output of<span>\u00a0<\/span><code>splitString<\/code><\/p>\n<\/blockquote>\n<p dir=\"auto\">If the regex check succeeds, the variable<span>\u00a0<\/span><code>rbx_1<\/code><span>\u00a0<\/span>will be set to 0, and if it fails, it will be set to 4.<\/p>\n<p dir=\"auto\">At the bottom of the function, we can see that the function returns<span>\u00a0<\/span><code>rbx_1<\/code>. Throughout the function, we can see that<span>\u00a0<\/span><code>rbx_1<\/code><span>\u00a0<\/span>is set to different values if either the base64 check or the email check fail, but set to 0 if the checks succeed. Therefore, we can assume that 0 is returned if checkFormat succeeds.<\/p>\n<div class=\"markdown-heading\" dir=\"auto\">\n<h3 class=\"heading-element\" dir=\"auto\"><strong>What we have learned so far:<\/strong><\/h3>\n<h6 class=\"heading-element\" dir=\"auto\"><span style=\"font-size: 1.25rem\">There are 5 elements in the license: Email, Start Date, Expiration Date, Secret Number, and License Type.<\/span><\/h6>\n<\/div>\n<ul dir=\"auto\">\n<li>The License is base64 encoded<\/li>\n<li>The fields are separated by a comma<\/li>\n<li>Email is the first field of the license<\/li>\n<\/ul>\n<div class=\"markdown-heading\" dir=\"auto\">\n<h3 class=\"heading-element\" dir=\"auto\">Finding the rest of the fields<\/h3>\n<h3 class=\"heading-element\" dir=\"auto\"><span style=\"font-size: 1.25rem\">Currently we know that the first field is an email address, but we don&#8217;t know the rest of the structure of the license. We can look for other uses of<\/span><span style=\"font-size: 1.25rem\">\u00a0<\/span><code>splitString<\/code><span style=\"font-size: 1.25rem\">\u00a0<\/span><span style=\"font-size: 1.25rem\">to try and identify other fields in the license. By searching &#8220;splitString&#8221; in symbols, then selecting the function, we can see the xrefs below the symbols field:<\/span><\/h3>\n<\/div>\n<p dir=\"auto\"><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/blob\/master\/walkthrough\/imgs\/splitStringCheck.png\"><img decoding=\"async\" src=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/raw\/master\/walkthrough\/imgs\/splitStringCheck.png\" alt=\"img.png\" \/><\/a><\/p>\n<p dir=\"auto\">While 2 of the usages are<span>\u00a0<\/span><code>License::checkFormat<\/code>, the other usage is<span>\u00a0<\/span><code>License::importLicense<\/code>. We can select that entry in the Cross References pane to jump to that usage of splitString<\/p>\n<p dir=\"auto\"><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/blob\/master\/walkthrough\/imgs\/licImport.png\"><img decoding=\"async\" src=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/raw\/master\/walkthrough\/imgs\/licImport.png\" alt=\"img.png\" \/><\/a><\/p>\n<p dir=\"auto\">The function<span>\u00a0<\/span><code>License::importLicense<\/code><span>\u00a0<\/span>is very dense, but we can start to understand it by renaming variables. We see that<span>\u00a0<\/span><code>b64_decode<\/code><span>\u00a0<\/span>is called almost immediately and has its output set to<span>\u00a0<\/span><code>var_38<\/code>, so it can be renamed to<span>\u00a0<\/span><code>decoded_string<\/code><span>\u00a0<\/span>As with<span>\u00a0<\/span><code>License::checkFormat<\/code>, we can see that<span>\u00a0<\/span><code>splitString<\/code><span>\u00a0<\/span>is again called with<span>\u00a0<\/span><code>decoded_string<\/code><span>\u00a0<\/span>and a comma as arguments (although as before, the comma is viewable as its hex equivalent<span>\u00a0<\/span><code>0x2c<\/code>).<\/p>\n<p dir=\"auto\">It becomes clear that the rest of the function is going through the elements of the split license index by index, and saving them to indices within<span>\u00a0<\/span><code>arg1<\/code><\/p>\n<blockquote>\n<p dir=\"auto\">Note: Since<span>\u00a0<\/span><code>License<\/code><span>\u00a0<\/span>is an object,<span>\u00a0<\/span><code>arg1<\/code><span>\u00a0<\/span>(as decompiled from the Linux binary) is the<span>\u00a0<\/span><code>License<\/code><span>\u00a0<\/span>object passed to all member functions of the class. Therefore, indexing into<span>\u00a0<\/span><code>arg1<\/code><span>\u00a0<\/span>would be setting fields of a License object.<\/p>\n<\/blockquote>\n<p dir=\"auto\">Using the rest of the function, we can start to build a picture of the data in each field of the license.<\/p>\n<p dir=\"auto\"><code>std::string::operator=(((char*)arg1 + 0x80), std::vector&lt;std::string&gt;::operator[](&amp;split_string_output, 0));<\/code>: We know that the first field of the license is at the first index,<span>\u00a0<\/span><code>split_string_output[0]<\/code>, and is the email address.<\/p>\n<p dir=\"auto\"><code>std::string::operator=(&amp;arg1[0x14], std::vector&lt;std::string&gt;::operator[](&amp;split_string_output, 1));<\/code>: The second field of the license is a string<\/p>\n<div class=\"highlight highlight-source-c notranslate position-relative overflow-auto\" dir=\"auto\">\n<pre><span class=\"pl-s1\">arg1<\/span>[<span class=\"pl-c1\">0x1c<\/span>] <span class=\"pl-c1\">=<\/span> <span class=\"pl-s1\">std<\/span>::stol(<span class=\"pl-smi\">std<\/span>::<span class=\"pl-s1\">vector<\/span><span class=\"pl-c1\">&lt;<\/span><span class=\"pl-s1\">std<\/span>::<span class=\"pl-s1\">string<\/span><span class=\"pl-c1\">&gt;<\/span>::<span class=\"pl-s1\">operator<\/span>[<span class=\"pl-s1\"><\/span>](<span class=\"pl-c1\">&amp;<\/span><span class=\"pl-s1\">split_string_output<\/span>, <span class=\"pl-c1\">2<\/span>), <span class=\"pl-s1\">nullptr<\/span>, <span class=\"pl-c1\">0xa<\/span>);\r\n<span class=\"pl-s1\">arg1<\/span>[<span class=\"pl-c1\">0x1d<\/span>] <span class=\"pl-c1\">=<\/span> <span class=\"pl-s1\">std<\/span>::stol(<span class=\"pl-smi\">std<\/span>::<span class=\"pl-s1\">vector<\/span><span class=\"pl-c1\">&lt;<\/span><span class=\"pl-s1\">std<\/span>::<span class=\"pl-s1\">string<\/span><span class=\"pl-c1\">&gt;<\/span>::<span class=\"pl-s1\">operator<\/span>[<span class=\"pl-s1\"><\/span>](<span class=\"pl-c1\">&amp;<\/span><span class=\"pl-s1\">split_string_output<\/span>, <span class=\"pl-c1\">3<\/span>), <span class=\"pl-s1\">nullptr<\/span>, <span class=\"pl-c1\">0xa<\/span>);\r\n\r\n<code>std::stol<\/code><span style=\"font-size: 1.25rem;font-family: ShermanSans, Verdana, sans-serif\">\u00a0<\/span><span style=\"font-size: 1.25rem;font-family: ShermanSans, Verdana, sans-serif\">is a function that converts a string to a long integer. Therefore, the third and fourth fields of the license are interpreted as numbers<\/span><\/pre>\n<\/div>\n<p dir=\"auto\"><code>std::string::operator=(&amp;arg1[0x18], std::vector&lt;std::string&gt;::operator[](&amp;split_string_output, 4));<\/code>: The fifth and last field of the license is a string<\/p>\n<div class=\"markdown-heading\" dir=\"auto\">\n<h6 class=\"heading-element\" dir=\"auto\">What we have learned so far:<\/h6>\n<ul>\n<li class=\"heading-element\" dir=\"auto\"><span style=\"font-size: 1.25rem\">The license is base64 encoded<\/span><\/li>\n<\/ul>\n<\/div>\n<ul dir=\"auto\">\n<li>\n<p dir=\"auto\">The fields are separated by a comma<\/p>\n<\/li>\n<li>\n<p dir=\"auto\">The format of the license is as follows:<\/p>\n<ol dir=\"auto\">\n<li>Email<\/li>\n<li>String<\/li>\n<li>Number<\/li>\n<li>Number<\/li>\n<li>String<\/li>\n<\/ol>\n<\/li>\n<li>\n<p dir=\"auto\">the five required fields are:<\/p>\n<ol dir=\"auto\">\n<li>Email<\/li>\n<li>Start Date<\/li>\n<li>Expiration Date<\/li>\n<li>Secret Number<\/li>\n<li>License Type<\/li>\n<\/ol>\n<\/li>\n<\/ul>\n<p dir=\"auto\">It would be unreasonable to assume that the start and end date were different data types (e.g. one being a string and the other being a number), so we can assume that the start and end date are both numbers or both strings.<\/p>\n<p dir=\"auto\">All that remains to figure out is:<\/p>\n<ul dir=\"auto\">\n<li>Whether the dates are stored as numbers or strings<\/li>\n<li>How the license type is stored<\/li>\n<li>How the secret number is stored<\/li>\n<\/ul>\n<div class=\"markdown-heading\" dir=\"auto\">\n<h3 class=\"heading-element\" dir=\"auto\">Diversion: Looking at the error codes:<\/h3>\n<h3 class=\"heading-element\" dir=\"auto\"><span style=\"font-size: 1.25rem\">When reversing the<\/span><span style=\"font-size: 1.25rem\">\u00a0<\/span><code>License::checkFormat<\/code><span style=\"font-size: 1.25rem\">\u00a0<\/span><span style=\"font-size: 1.25rem\">function, we saw that the function would return 0 if it succeeded, and 4 if the email check failed.<\/span><\/h3>\n<\/div>\n<p dir=\"auto\">It may be useful to find other error codes to try and figure out the missing fields of the license. By returning to the string search for one of the error messages, clicking on one of the strings, for example, &#8220;Invalid secret number&#8221;, we can view the cross-references to that string.<\/p>\n<p dir=\"auto\"><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/blob\/master\/walkthrough\/imgs\/findingErrorMessageMappt1.png\"><img decoding=\"async\" src=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/raw\/master\/walkthrough\/imgs\/findingErrorMessageMappt1.png\" alt=\"img.png\" \/><\/a><\/p>\n<p dir=\"auto\">By double-clicking on either of the cross-references that reference that error message, we are taken to<span>\u00a0<\/span><code>License::License()<\/code><span>\u00a0<\/span>The function has a list of setting ints to different values, 1-9, then setting a<span>\u00a0<\/span><code>std::pair&lt;int32, char const[some length]&gt;<\/code><\/p>\n<p dir=\"auto\">After renaming the variables, here is the function:<span>\u00a0<\/span><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/blob\/master\/walkthrough\/imgs\/err_msgs_pt2.png\"><img decoding=\"async\" src=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/raw\/master\/walkthrough\/imgs\/err_msgs_pt2.png\" alt=\"img.png\" \/><\/a><\/p>\n<p dir=\"auto\">This can also be interpreted as a table of error codes and their corresponding error messages:<\/p>\n<table>\n<thead>\n<tr>\n<th>Error Code<\/th>\n<th>Error Message<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>0<\/td>\n<td>License Successfully Verified!<\/td>\n<\/tr>\n<tr>\n<td>1<\/td>\n<td>Invalid format<\/td>\n<\/tr>\n<tr>\n<td>2<\/td>\n<td>Invalid number of fields &#8211; The license needs more information<\/td>\n<\/tr>\n<tr>\n<td>3<\/td>\n<td>Invalid secret number<\/td>\n<\/tr>\n<tr>\n<td>4<\/td>\n<td>Invalid licensee email address<\/td>\n<\/tr>\n<tr>\n<td>5<\/td>\n<td>License hasn&#8217;t begun yet<\/td>\n<\/tr>\n<tr>\n<td>6<\/td>\n<td>License expired<\/td>\n<\/tr>\n<tr>\n<td>7<\/td>\n<td>Invalid license dates. Time travel is prohibited<\/td>\n<\/tr>\n<tr>\n<td>8<\/td>\n<td>Invalid license type<\/td>\n<\/tr>\n<tr>\n<td>9<\/td>\n<td>Unknown error<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;<\/p>\n<p dir=\"auto\">By using the values from the table, we can begin to figure out the remaining fields of the license.<\/p>\n<div class=\"markdown-heading\" dir=\"auto\">\n<h3 class=\"heading-element\" dir=\"auto\">Figuring out the date format<\/h3>\n<h3 class=\"heading-element\" dir=\"auto\"><span style=\"font-size: 1.25rem\">We will start by searching the symbols for<\/span><span style=\"font-size: 1.25rem\">\u00a0<\/span><code>License::<\/code><span style=\"font-size: 1.25rem\">\u00a0<\/span><span style=\"font-size: 1.25rem\">and looking for likely functions that could tell us more about the format of the date<\/span><\/h3>\n<\/div>\n<p dir=\"auto\">The list of functions returned by the search includes<span>\u00a0<\/span><code>License::timeCheck()<\/code>, so we&#8217;ll go there by clicking the function name:<span>\u00a0<\/span><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/blob\/master\/walkthrough\/imgs\/timecheck.png\"><img decoding=\"async\" src=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/raw\/master\/walkthrough\/imgs\/timecheck.png\" alt=\"img.png\" \/><\/a><\/p>\n<p dir=\"auto\">The first thing that the function does is get the current time using the system function, which returns a unix timestamp. For clarity, we will rename the variable to<span>\u00a0<\/span><code>current_time<\/code>.<\/p>\n<blockquote>\n<p dir=\"auto\">Note: A Unix timestamp is the number of seconds that have passed since January 1, 1970. It is a common way to store time in programming.<\/p>\n<\/blockquote>\n<p dir=\"auto\">The other two variables referenced in this function are<span>\u00a0<\/span><code>arg1 + 0xe0<\/code><span>\u00a0<\/span>and<span>\u00a0<\/span><code>arg1 + 0xe8<\/code>. These are likely the start and end dates of the license, but we can&#8217;t be sure which is which yet.<\/p>\n<p dir=\"auto\">We can see that there are 4 possible return values from this function: 7, 5, 0, and 6. Assuming that the return values are error codes, we can refer back to the table of error codes we made earlier.<\/p>\n<blockquote>\n<table>\n<thead>\n<tr>\n<th>Error Code<\/th>\n<th>Error Message<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>0<\/td>\n<td>License Successfully Verified!<\/td>\n<\/tr>\n<tr>\n<td>5<\/td>\n<td>License hasn&#8217;t begun yet<\/td>\n<\/tr>\n<tr>\n<td>6<\/td>\n<td>License expired<\/td>\n<\/tr>\n<tr>\n<td>7<\/td>\n<td>Invalid license dates. Time travel is prohibited<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/blockquote>\n<p dir=\"auto\">Using those error codes, we can can infer that the function is checking if the current time is between the start and end dates of the license. If the current time is before the start date, it will return 5, if it is after the end date, it will return 6, and if the current time is between the start and end dates, it will return 0. If the start date is after the end date, it will return 7.<\/p>\n<p dir=\"auto\">Because of the data types used, we know that the dates are saved as unix timestamps in the license, and that the start date is the first number, and the end date is the second number.<\/p>\n<div class=\"markdown-heading\" dir=\"auto\">\n<h3 class=\"heading-element\" dir=\"auto\">What we have learned so far:<\/h3>\n<h6 class=\"heading-element\" dir=\"auto\"><span style=\"font-size: 1.25rem\">The license is base64 encoded, with the 5 fields separated by commas.<\/span><\/h6>\n<\/div>\n<p dir=\"auto\">The dates are unix timestamps<\/p>\n<p dir=\"auto\">The discovered fields are as follows:<\/p>\n<ol dir=\"auto\">\n<li>Email<\/li>\n<li>Unknown string<\/li>\n<li>Start Date<\/li>\n<li>Expiration Date<\/li>\n<li>Unknown String<\/li>\n<\/ol>\n<p dir=\"auto\">All that is left is to figure out the secret number and the license type<\/p>\n<div class=\"markdown-heading\" dir=\"auto\">\n<h3 class=\"heading-element\" dir=\"auto\">Constructing a partial valid license<\/h3>\n<h3 class=\"heading-element\" dir=\"auto\"><span style=\"font-size: 1.25rem\">Now that we know the format of the license, and the majority of the license fields, we can begin to construct a partial license, and see what the program returns.<\/span><\/h3>\n<\/div>\n<p dir=\"auto\">To construct the license, I will use 2 websites to generate the unix timestamps and base64 encode the license, although anything that gets the job done is fine:<\/p>\n<ul dir=\"auto\">\n<li><a href=\"https:\/\/www.epochconverter.com\/\" rel=\"nofollow\">Epoch Converter &#8211; epochconverter.com<\/a><\/li>\n<li><a href=\"https:\/\/gchq.github.io\/CyberChef\/#recipe=To_Base64('A-Za-z0-9%2B\/%3D')\" rel=\"nofollow\">Base64 Encode &#8211; CyberChef<\/a><\/li>\n<\/ul>\n<blockquote>\n<p dir=\"auto\">Note: CyberChef is an incredibly powerful tool. The link to cyberchef pre-fills the recipe for base64 encoding, but you can construct your own recipes by dragging and dropping the operations you want to perform.<\/p>\n<\/blockquote>\n<p dir=\"auto\">Start by generating the timestamps for the start and end date of the license using the epoch converter, selecting any date in the future and any date in the past.<\/p>\n<p dir=\"auto\">In the &#8220;Input&#8221; field of CyberChef, enter the license fields separated by commas according to what we know so far:<\/p>\n<p dir=\"auto\"><code>email,unknown_string,start_date,expiration_date,unknown_string<\/code><\/p>\n<p dir=\"auto\">For example:<span>\u00a0<\/span><code>test@test.test,qwertyuiop,1694245945,1883634745,qwertyuiop<\/code><\/p>\n<p dir=\"auto\"><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/blob\/master\/walkthrough\/imgs\/cyberchefImage.png\"><img decoding=\"async\" src=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/raw\/master\/walkthrough\/imgs\/cyberchefImage.png\" alt=\"img.png\" \/><\/a><\/p>\n<p dir=\"auto\">After encoding the license, paste it into the license field of the program and press &#8220;Check License&#8221; to see what the program says:<\/p>\n<p dir=\"auto\"><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/blob\/master\/walkthrough\/imgs\/firstTrial.png\"><img decoding=\"async\" src=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/raw\/master\/walkthrough\/imgs\/firstTrial.png\" alt=\"img.png\" \/><\/a><\/p>\n<p dir=\"auto\">Congratulations! The email, format, and date checks have been passed, now the secretNumber check needs to be passed:<\/p>\n<div class=\"markdown-heading\" dir=\"auto\">\n<h3 class=\"heading-element\" dir=\"auto\">Secret Number check:<\/h3>\n<h3 class=\"heading-element\" dir=\"auto\"><span style=\"font-size: 1.25rem\">Back to Binary Ninja, we can search for the function that checks the secret number. By searching for<\/span><span style=\"font-size: 1.25rem\">\u00a0<\/span><code>License::isValidSecretNumber<\/code><span style=\"font-size: 1.25rem\">\u00a0<\/span><span style=\"font-size: 1.25rem\">in the symbols, we can find the function that checks the secret number.<\/span><span style=\"font-size: 1.25rem\">\u00a0<\/span><\/h3>\n<\/div>\n<p dir=\"auto\"><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/blob\/master\/walkthrough\/imgs\/secretNumberCheck.png\"><img decoding=\"async\" src=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/raw\/master\/walkthrough\/imgs\/secretNumberCheck.png\" alt=\"img.png\" \/><\/a><\/p>\n<p dir=\"auto\">The function is very complex. While it would be possible to reverse engineer the function, we can see that it is only ever called in a single location, by looking at the Cross References pane. By clicking on the cross-reference, we jump to that function,<span>\u00a0<\/span><code>License::checkNumber<\/code>, which we see has many more references.<\/p>\n<p dir=\"auto\"><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/blob\/master\/walkthrough\/imgs\/checkNumber.png\"><img decoding=\"async\" src=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/raw\/master\/walkthrough\/imgs\/checkNumber.png\" alt=\"img.png\" \/><\/a><\/p>\n<p dir=\"auto\">There are only 2 possible return values from this function: 3 and 0. Looking back to the table of error codes:<\/p>\n<blockquote>\n<table>\n<thead>\n<tr>\n<th>Error Code<\/th>\n<th>Error Message<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>0<\/td>\n<td>License Successfully Verified!<\/td>\n<\/tr>\n<tr>\n<td>3<\/td>\n<td>Invalid secret number<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/blockquote>\n<p dir=\"auto\">This function is likely actually in charge of checking the secret number, and is much simpler than the<span>\u00a0<\/span><code>License::isValidSecretNumber<\/code><span>\u00a0<\/span>function<\/p>\n<p dir=\"auto\">Still, the function calls<span>\u00a0<\/span><code>License::isValidSecretNumber<\/code><span>\u00a0<\/span>with the secret number as an argument, so that function is still needed.<\/p>\n<p dir=\"auto\">However, we can patch the function to not check the output of<span>\u00a0<\/span><code>isValidSecretNumber<\/code><span>\u00a0<\/span>and always return 0. To do this, we will select the entire function but the return statement, right-click, and select &#8220;Patch Function&#8221;, then &#8220;Convert to NOP&#8221;<\/p>\n<p dir=\"auto\">NOP stands for No Operation, and is an assembly instruction that does nothing. By converting the function to NOP, we are effectively disabling the function, ensuring that it will always return 0.<\/p>\n<p dir=\"auto\"><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/blob\/master\/walkthrough\/imgs\/patching.png\"><img decoding=\"async\" src=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/raw\/master\/walkthrough\/imgs\/patching.png\" alt=\"img.png\" \/><\/a><\/p>\n<p dir=\"auto\">To actually apply the changes to the binary, we will save as, then select &#8220;Save file contents only&#8221;, and save the file.<\/p>\n<p dir=\"auto\">Now we can run the modified program and enter the same license as before, and see how the behavior changes:<\/p>\n<p dir=\"auto\"><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/blob\/master\/walkthrough\/imgs\/cheers.png\"><img decoding=\"async\" src=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/raw\/master\/walkthrough\/imgs\/cheers.png\" alt=\"img.png\" \/><\/a><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/blob\/master\/walkthrough\/imgs\/badLicenseType.png\"><img decoding=\"async\" src=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/raw\/master\/walkthrough\/imgs\/badLicenseType.png\" alt=\"img.png\" \/><\/a><\/p>\n<p dir=\"auto\">Now that the secret number is patched, the program congratulates you on patching the number check (assuming the number check is patched successfully). However, the license type is still missing, and the &#8220;Invalid license type&#8221; error still appears.<\/p>\n<div class=\"markdown-heading\" dir=\"auto\">\n<h3 class=\"heading-element\" dir=\"auto\">License Type:<\/h3>\n<h3 class=\"heading-element\" dir=\"auto\"><span style=\"font-size: 1.25rem\">We could start by assuming that the license type is a string, and return to the string table section in Binary Ninja by searching again for any of the error messages in the strings menu.<\/span><\/h3>\n<\/div>\n<p dir=\"auto\">Returning to the strings table beneath the error messages, we see strings such as, &#8220;Professional&#8221;, &#8220;Standard&#8221;, and &#8221; Trial&#8221;. These are likely the possible license types. Using the same strategy as was used to construct the error code table, we can also construct a table of license codes and types by selecting a license, then using the Cross References to see where it is referenced.<\/p>\n<p dir=\"auto\"><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/blob\/master\/walkthrough\/imgs\/license_types_Part1.png\"><img decoding=\"async\" src=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/raw\/master\/walkthrough\/imgs\/license_types_Part1.png\" alt=\"img.png\" \/><\/a><\/p>\n<p dir=\"auto\"><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/blob\/master\/walkthrough\/imgs\/license_types_Part2.png\"><img decoding=\"async\" src=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/raw\/master\/walkthrough\/imgs\/license_types_Part2.png\" alt=\"img.png\" \/><\/a><\/p>\n<p dir=\"auto\">Back in<span>\u00a0<\/span><code>License::License()<\/code>, we can see all of the license types and their corresponding codes, allowing the construction of a table of the License types:<\/p>\n<table>\n<thead>\n<tr>\n<th>License Code<\/th>\n<th>License Type<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>LIC_UNLIC<\/code><\/td>\n<td>Trialv<\/td>\n<\/tr>\n<tr>\n<td><code>LIC_STD<\/code><\/td>\n<td>Standard<\/td>\n<\/tr>\n<tr>\n<td><code>LIC_PRO<\/code><\/td>\n<td>Professional<\/td>\n<\/tr>\n<tr>\n<td><code>LIC_PROPLUS<\/code><\/td>\n<td>Professional Plus<\/td>\n<\/tr>\n<tr>\n<td><code>LIC_APPLE<\/code><\/td>\n<td>Professional Plus Max Pro Ultra<\/td>\n<\/tr>\n<tr>\n<td><code>LIC_ENTR<\/code><\/td>\n<td>Enterprise<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;<\/p>\n<p dir=\"auto\">Now that we have the license types, we can construct a license with the license type included, and see if the program accepts the license:<\/p>\n<div class=\"markdown-heading\" dir=\"auto\">\n<h3 class=\"heading-element\" dir=\"auto\">Valid License Construction:<\/h3>\n<h3 class=\"heading-element\" dir=\"auto\"><span style=\"font-size: 1.25rem\">We still don&#8217;t know where the license type and the secret number are in the license but we can simply construct 2 licenses, one with the license type in the first unknown spot, and one with the license type in the second unknown spot.<\/span><\/h3>\n<\/div>\n<p dir=\"auto\">Known Fields:<span>\u00a0<\/span><code>email,unknown_string,start_date,expiration_date,unknown_string<\/code><\/p>\n<p dir=\"auto\">Attempts:<span>\u00a0<\/span><code>email,license_type,start_date,expiration_date,secret_number<\/code><span>\u00a0<\/span>and<span>\u00a0<\/span><code>email,secret_number,start_date,expiration_date,license_type<\/code><\/p>\n<p dir=\"auto\">Examples:<span>\u00a0<\/span><code>test@test.test,LIC_UNLIC,1694245945,1883634745,qwertyuiop<\/code>, and<span>\u00a0<\/span><code>test@test.test,qwertyuiop,1694245945,1883634745,LIC_UNLIC<\/code><\/p>\n<p dir=\"auto\">Using CyberChef to base64 encode each of the licenses, we can try each of them in the program to see if they are accepted as valid licenses<\/p>\n<p dir=\"auto\"><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/blob\/master\/walkthrough\/imgs\/cyberchef2.png\"><img decoding=\"async\" src=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/raw\/master\/walkthrough\/imgs\/cyberchef2.png\" alt=\"img.png\" \/><\/a><\/p>\n<blockquote>\n<p dir=\"auto\">Note: I used the fork operator, which will cause the To Base64 operation to be performed on each of the input lines<\/p>\n<\/blockquote>\n<p dir=\"auto\">By trial and error, we can see that the license with the license type in the first unknown spot is accepted as a valid license, and the license with the license type in the second unknown spot is not accepted.<\/p>\n<p dir=\"auto\">Therefore, the correct License format is:<span>\u00a0<\/span><code>email,license_type,start_date,expiration_date,secret_number<\/code><\/p>\n<p dir=\"auto\">Congratulations! At this point, you should be able to make your own license.<\/p>\n<p dir=\"auto\"><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/blob\/master\/walkthrough\/imgs\/homework.png\"><img decoding=\"async\" src=\"https:\/\/github.com\/TownsendSP\/ISC_Crackme\/raw\/master\/walkthrough\/imgs\/homework.png\" alt=\"img.png\" \/><\/a><span>\u00a0<\/span>However, you may notice that the status text box at the top says &#8220;CRACKED&#8221;, not &#8220;LICENSED&#8221;, like my example at the beginning showed.<\/p>\n<p dir=\"auto\">Throughout the program, I have placed checks that make check whether the program has been patched. Note that even if you provide a valid number secret number and the secret number check is patched, the program will still display &#8220;CRACKED&#8221; instead of &#8220;LICENSED&#8221;. There are several approaches you may take to getting it to display &#8220;LICENSED&#8221; (And bypassing the popup congratulating you on patching the number check):<\/p>\n<ul dir=\"auto\">\n<li>Finding and patching all the checks for the patched functions<\/li>\n<li>Reverse engineering the secret number check and generating a valid secret number<\/li>\n<li>Reimplementing the secret number check in another language and brute-force checking for valid serial numbers<\/li>\n<li>Patching out the checks that determine whether to display the &#8220;CRACKED&#8221; message or the &#8220;Congratulations on patching message&#8221;<\/li>\n<li>Figuring out what algorithm I used to determine whether a secret number is valid or not (I didn&#8217;t create my own algorithm)<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>ISC_Crackme Walkthrough By Townsend Southard Pantano Github This simple license validator is designed to expose the user to a revere engineering workflow, using Binary Ninja to reverse the license format and validation to bypass the license check and generate a license that the program thinks is valid. The goal: Generate your own license that will&hellip;<\/p>\n","protected":false},"author":301,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1348","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"acf":[],"_links":{"self":[{"href":"https:\/\/studentorgs.syr.edu\/isc\/wp-json\/wp\/v2\/posts\/1348","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/studentorgs.syr.edu\/isc\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/studentorgs.syr.edu\/isc\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/studentorgs.syr.edu\/isc\/wp-json\/wp\/v2\/users\/301"}],"replies":[{"embeddable":true,"href":"https:\/\/studentorgs.syr.edu\/isc\/wp-json\/wp\/v2\/comments?post=1348"}],"version-history":[{"count":1,"href":"https:\/\/studentorgs.syr.edu\/isc\/wp-json\/wp\/v2\/posts\/1348\/revisions"}],"predecessor-version":[{"id":1349,"href":"https:\/\/studentorgs.syr.edu\/isc\/wp-json\/wp\/v2\/posts\/1348\/revisions\/1349"}],"wp:attachment":[{"href":"https:\/\/studentorgs.syr.edu\/isc\/wp-json\/wp\/v2\/media?parent=1348"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/studentorgs.syr.edu\/isc\/wp-json\/wp\/v2\/categories?post=1348"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/studentorgs.syr.edu\/isc\/wp-json\/wp\/v2\/tags?post=1348"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}