unicorn icon indicating copy to clipboard operation
unicorn copied to clipboard

mu.mem_write(BASE, shellcode) issue

Open 0xdarkfloyd opened this issue 2 years ago • 8 comments

Dear Dr. Quynh,

I have tried to play around with the shellcode analysis: https://eternal.red/2018/unicorn-engine-tutorial/

However, I have got the following error, do you have any hints? Thank you.

Regards, Anthony


Exploits-MBP:unicorn exploitmachine$ python3 solve2.py
Traceback (most recent call last):
  File "solve2.py", line 17, in <module>
    mu.mem_write(BASE, shellcode)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/unicorn/unicorn.py", line 585, in mem_write
    status = _uc.uc_mem_write(self._uch, address, data, len(data))
ctypes.ArgumentError: argument 3: <class 'TypeError'>: wrong type
Exploits-MBP:unicorn exploitmachine$ nano solve2.py
Exploits-MBP:unicorn exploitmachine$ 

0xdarkfloyd avatar Aug 13 '22 15:08 0xdarkfloyd

It's weird, how to reproduce?

wtdcode avatar Aug 13 '22 19:08 wtdcode

I run it on :

  Model Name:	MacBook Pro
  Model Identifier:	MacBookPro15,1
  Processor Name:	6-Core Intel Core i9
  Processor Speed:	2.9 GHz
  Number of Processors:	1
  Total Number of Cores:	6
  L2 Cache (per Core):	256 KB
  L3 Cache:	12 MB
  Hyper-Threading Technology:	Enabled
  Memory:	32 GB
  System Firmware Version:	1731.140.2.0.0 (iBridge: 19.16.16064.0.0,0)
  OS Loader Version:	540.120.3~19
  Serial Number (system):	C02XC0SNJG5K
  Hardware UUID:	DB77C90B-45AF-5D5C-858B-A96D18D2295E
  Provisioning UDID:	DB77C90B-45AF-5D5C-858B-A96D18D2295E
  Activation Lock Status:	Disabled

Here are my findings below:

  1. The code I run is in Task 2 in solutions:
from unicorn import *
from unicorn.x86_const import *

shellcode = "\xe8\xff\xff\xff\xff\xc0\x5d\x6a\x05\x5b\x29\xdd\x83\xc5\x4e\x89\xe9\x6a\x02\x03\x0c\x24\x5b\x31\xd2\x66\xba\x12\x00\x8b\x39\xc1\xe7\x10\xc1\xef\x10\x81\xe9\xfe\xff\xff\xff\x8b\x45\x00\xc1\xe0\x10\xc1\xe8\x10\x89\xc3\x09\xfb\x21\xf8\xf7\xd0\x21\xd8\x66\x89\x45\x00\x83\xc5\x02\x4a\x85\xd2\x0f\x85\xcf\xff\xff\xff\xec\x37\x75\x5d\x7a\x05\x28\xed\x24\xed\x24\xed\x0b\x88\x7f\xeb\x50\x98\x38\xf9\x5c\x96\x2b\x96\x70\xfe\xc6\xff\xc6\xff\x9f\x32\x1f\x58\x1e\x00\xd3\x80" 


BASE = 0x400000
STACK_ADDR = 0x0
STACK_SIZE = 1024*1024

mu = Uc (UC_ARCH_X86, UC_MODE_32)

mu.mem_map(BASE, 1024*1024)
mu.mem_map(STACK_ADDR, STACK_SIZE)


mu.mem_write(BASE, shellcode)
mu.reg_write(UC_X86_REG_ESP, STACK_ADDR + STACK_SIZE/2)

def syscall_num_to_name(num):
    syscalls = {1: "sys_exit", 15: "sys_chmod"}
    return syscalls[num]

def hook_code(mu, address, size, user_data):
    #print('>>> Tracing instruction at 0x%x, instruction size = 0x%x' %(address, size))  
    
    machine_code = mu.mem_read(address, size)
    if machine_code == "\xcd\x80":
        
        r_eax = mu.reg_read(UC_X86_REG_EAX)
        r_ebx = mu.reg_read(UC_X86_REG_EBX)
        r_ecx = mu.reg_read(UC_X86_REG_ECX)
        r_edx = mu.reg_read(UC_X86_REG_EDX)
        syscall_name = syscall_num_to_name(r_eax)
        
        print "--------------"
        print "We intercepted system call: "+syscall_name
        
        if syscall_name == "sys_chmod":
            s = mu.mem_read(r_ebx, 20).split("\x00")[0]
            print "arg0 = 0x%x -> %s" % (r_ebx, s)
            print "arg1 = " + oct(r_ecx)
        elif syscall_name == "sys_exit":
            print "arg0 = " + hex(r_ebx)
            exit()
        
        mu.reg_write(UC_X86_REG_EIP, address + size)
        
mu.hook_add(UC_HOOK_CODE, hook_code)

mu.emu_start(BASE, BASE-1)
  1. I try to run another code from Sakura (https://xz.aliyun.com/t/7545):
from unicorn import *
from unicorn.x86_const import *

mu = Uc(UC_ARCH_X86, UC_MODE_32)
BASE = 0x400000
STACK_ADDR = 0x0
STACK_SIZE = 1024*1024
mu.mem_map(BASE, 1024*1024)
mu.mem_map(STACK_ADDR, STACK_SIZE)

shellcode = b"\xe8\xff\xff\xff\xff\xc0\x5d\x6a\x05\x5b\x29\xdd\x83\xc5\x4e\x89\xe9\x6a\x02\x03\x0c\x24\x5b\x31\xd2\x66\xba\x12\x00\x8b\x39\xc1\xe7\x10\xc1\xef\x10\x81\xe9\xfe\xff\xff\xff\x8b\x45\x00\xc1\xe0\x10\xc1\xe8\x10\x89\xc3\x09\xfb\x21\xf8\xf7\xd0\x21\xd8\x66\x89\x45\x00\x83\xc5\x02\x4a\x85\xd2\x0f\x85\xcf\xff\xff\xff\xec\x37\x75\x5d\x7a\x05\x28\xed\x24\xed\x24\xed\x0b\x88\x7f\xeb\x50\x98\x38\xf9\x5c\x96\x2b\x96\x70\xfe\xc6\xff\xc6\xff\x9f\x32\x1f\x58\x1e\x00\xd3\x80"

mu.mem_write(BASE, shellcode)
mu.reg_write(UC_X86_REG_ESP, STACK_ADDR + STACK_SIZE-1)


def hook_code(mu, address, size, user_data):
    # print('>>> Tracing instruction at 0x%x, instruction size = 0x%x' %(address, size))
    code = mu.mem_read(address,size)
    # print(code)
    if code == b"\xcd\x80":
        print('>>> Tracing instruction at 0x%x, instruction size = 0x%x' %(address, size))
        eax = mu.reg_read(UC_X86_REG_EAX)
        ebx = mu.reg_read(UC_X86_REG_EBX)
        ecx = mu.reg_read(UC_X86_REG_ECX)
        edx = mu.reg_read(UC_X86_REG_EDX)
        print("{}: {} {} {}".format(eax,ebx,ecx,edx))
        if(eax == 15):
            file_name = bytes(mu.mem_read(ebx,32)).split(b'\x00')[0]
            print("file_name is {}".format(file_name))
        mu.reg_write(UC_X86_REG_EIP, address+size)


mu.hook_add(UC_HOOK_CODE, hook_code)
mu.emu_start(BASE,BASE+len(shellcode))

It is okay but tracing to second time is problematic:

Exploits-MBP:unicorn exploitmachine$ python3 solve2a.py
>>> Tracing instruction at 0x40006b, instruction size = 0x2
15: 4194392 438 0
file_name is b'/etc/shadow'
>>> Tracing instruction at 0x400070, instruction size = 0x2
1: 4194392 438 0
Traceback (most recent call last):
  File "solve2a.py", line 35, in <module>
    mu.emu_start(BASE,BASE+len(shellcode))
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/unicorn/unicorn.py", line 548, in emu_start
    raise UcError(status)
unicorn.unicorn.UcError: Invalid memory fetch (UC_ERR_FETCH_UNMAPPED)
Exploits-MBP:unicorn exploitmachine$ 
  1. When I try to run task 3 (https://eternal.red/2018/unicorn-engine-tutorial/#task-3) code on my Mac OS:
from unicorn import *
from unicorn.x86_const import *
import struct

 
def read(name):
    with open(name) as f:
        return f.read()
        
def u32(data):
    return struct.unpack("I", data)[0]
    
def p32(num):
    return struct.pack("I", num)

mu = Uc (UC_ARCH_X86, UC_MODE_32)

BASE = 0x08048000
STACK_ADDR = 0x0
STACK_SIZE = 1024*1024

mu.mem_map(BASE, 1024*1024)
mu.mem_map(STACK_ADDR, STACK_SIZE)

 
mu.mem_write(BASE, read("./function"))
r_esp = STACK_ADDR + (STACK_SIZE/2)     #ESP points to this address at function call

STRING_ADDR = 0x0
mu.mem_write(STRING_ADDR, "batman\x00") #write "batman" somewhere. We have choosen an address 0x0 which belongs to the stack.

mu.reg_write(UC_X86_REG_ESP, r_esp)     #set ESP
mu.mem_write(r_esp+4, p32(5))           #set the first argument. It is integer 5
mu.mem_write(r_esp+8, p32(STRING_ADDR)) #set the second argument. This is a pointer to the string "batman"


mu.emu_start(0x8048464, 0x804849A)      #start emulation from the beginning of super_function, end at RET instruction
return_value = mu.reg_read(UC_X86_REG_EAX)
print "The returned value is: %d" % return_value

I have changed the base address and superfunction offset:

0000057b <super_function>:
     57b: 55                           	pushl	%ebp
     57c: 89 e5                        	movl	%esp, %ebp
     57e: e8 53 00 00 00               	calll	0x5d6 <__x86.get_pc_thunk.ax>
     583: 05 7d 1a 00 00               	addl	$6781, %eax             # imm = 0x1A7D
     588: 83 7d 08 05                  	cmpl	$5, 8(%ebp)
     58c: 75 1d                        	jne	0x5ab <super_function+0x30>
     58e: 8d 80 60 e6 ff ff            	leal	-6560(%eax), %eax
     594: 50                           	pushl	%eax
     595: ff 75 0c                     	pushl	12(%ebp)
     598: e8 70 ff ff ff               	calll	0x50d <strcmp>
     59d: 83 c4 08                     	addl	$8, %esp
     5a0: 85 c0                        	testl	%eax, %eax
     5a2: 75 07                        	jne	0x5ab <super_function+0x30>
     5a4: b8 01 00 00 00               	movl	$1, %eax
     5a9: eb 05                        	jmp	0x5b0 <super_function+0x35>
     5ab: b8 00 00 00 00               	movl	$0, %eax
     5b0: c9                           	leave
     5b1: c2 08 00                     	retl	$8
Exploits-MBP:unicorn exploitmachine$ objdump -d function

function:	file format elf32-i386

Disassembly of section .init:

00000378 <_init>:
     378: 53                           	pushl	%ebx
     379: 83 ec 08                     	subl	$8, %esp
     37c: e8 8f 00 00 00               	calll	0x410 <__x86.get_pc_thunk.bx>
     381: 81 c3 7f 1c 00 00            	addl	$7295, %ebx             # imm = 0x1C7F
     387: 8b 83 f4 ff ff ff            	movl	-12(%ebx), %eax
     38d: 85 c0                        	testl	%eax, %eax
     38f: 74 05                        	je	0x396 <_init+0x1e>
     391: e8 32 00 00 00               	calll	0x3c8 <function.c+0x3c8>
     396: 83 c4 08                     	addl	$8, %esp
     399: 5b                           	popl	%ebx
     39a: c3                           	retl

It gives: Without changing any offsets:

Exploits-MBP:unicorn exploitmachine$ python3 solve4.py
Traceback (most recent call last):
  File "solve4.py", line 23, in <module>
    mu.mem_map(BASE, 1024*1024)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/unicorn/unicorn.py", line 622, in mem_map
    raise UcError(status)
unicorn.unicorn.UcError: Invalid argument (UC_ERR_ARG)
Exploits-MBP:unicorn exploitmachine$ 

After change the offsets:

Exploits-MBP:unicorn exploitmachine$ python3 solve4.py
Traceback (most recent call last):
  File "solve4.py", line 24, in <module>
    mu.mem_map(STACK_ADDR, STACK_SIZE)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/unicorn/unicorn.py", line 622, in mem_map
    raise UcError(status)
unicorn.unicorn.UcError: Invalid memory mapping (UC_ERR_MAP)

Questions:

  1. Will it be related to my Mac runs on Intel Core i9? If yes, what is the change of the mem base? https://en.wikichip.org/wiki/intel/core_i9/i9-9900k

  2. I can run this code successfully without error: https://github.com/unicorn-engine/unicorn/blob/master/bindings/python/shellcode.py

  3. Are there any suggestions of changes of the above tutorial programs?

  4. Do you have any latest docker image of Unicorn engine available for download?

Thank you so much.

0xdarkfloyd avatar Aug 14 '22 03:08 0xdarkfloyd

It's weird, how to reproduce?

Yes, I have attached details in the immediate reply. Thank you so much, Lazymio, I heard your big name from XWings 👍

0xdarkfloyd avatar Aug 14 '22 04:08 0xdarkfloyd

(1) i think your Mac on x86 should be fine, so that is the the reason of the issue.

(4): no, we do not have docker support, since unicorn is easy enough to build & run.

aquynh avatar Aug 16 '22 16:08 aquynh

are you on Unicorn 2.0, or older version?

aquynh avatar Aug 16 '22 16:08 aquynh

are you on Unicorn 2.0, or older version?

Should be latest version as I freshly install and set it up.

0xdarkfloyd avatar Aug 16 '22 17:08 0xdarkfloyd

you can confirm the version with print(unicorn.__version__)

aquynh avatar Aug 16 '22 17:08 aquynh

image

It is 2.0.0.

0xdarkfloyd avatar Aug 16 '22 17:08 0xdarkfloyd

This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 15 days.

github-actions[bot] avatar Oct 16 '22 05:10 github-actions[bot]

Hey there @0xdarkfloyd ,

I was going through the same exercises and came across this issue too. I believe the wrong type is referring to the shellcode string, whereas it expects bytes. It was a very simple fix for me:

shellcode = b"\xe8\xff\xff\xff\xff\xc0\x5d..."

Hope this helps!

danielmoder avatar Nov 01 '22 20:11 danielmoder

Let me try thank you so much bro

On Wed, 2 Nov 2022 at 4:18 AM, danielmoder @.***> wrote:

Hey there @0xdarkfloyd https://github.com/0xdarkfloyd ,

I was going through the same exercises and came across this issue too. I believe the wrong type is referring to the shellcode string, whereas it expects bytes. It was a very simple fix for me:

shellcode = b"\xe8\xff\xff\xff\xff\xc0\x5d..."

Hope this helps!

— Reply to this email directly, view it on GitHub https://github.com/unicorn-engine/unicorn/issues/1677#issuecomment-1299088159, or unsubscribe https://github.com/notifications/unsubscribe-auth/AFKKU56MJVA5BEONORVBIP3WGF3I5ANCNFSM56OKIMCA . You are receiving this because you were mentioned.Message ID: @.***>

0xdarkfloyd avatar Nov 03 '22 13:11 0xdarkfloyd

Traceback (most recent call last): File "/home/hacker/solve2.py", line 18, in mu.reg_write(UC_X86_REG_ESP, STACK_ADDR + STACK_SIZE/2) File "/home/hacker/.local/lib/python3.10/site-packages/unicorn/unicorn.py", line 564, in reg_write return reg_write(functools.partial(_uc.uc_reg_write, self._uch), self._arch, reg_id, value) File "/home/hacker/.local/lib/python3.10/site-packages/unicorn/unicorn.py", line 375, in reg_write reg = ctypes.c_uint64(value) TypeError: 'float' object cannot be interpreted as an integer

Any thoughts about this error? Thank you all.

On Wed, Nov 2, 2022 at 4:18 AM danielmoder @.***> wrote:

Hey there @0xdarkfloyd https://github.com/0xdarkfloyd ,

I was going through the same exercises and came across this issue too. I believe the wrong type is referring to the shellcode string, whereas it expects bytes. It was a very simple fix for me:

shellcode = b"\xe8\xff\xff\xff\xff\xc0\x5d..."

Hope this helps!

— Reply to this email directly, view it on GitHub https://github.com/unicorn-engine/unicorn/issues/1677#issuecomment-1299088159, or unsubscribe https://github.com/notifications/unsubscribe-auth/AFKKU56MJVA5BEONORVBIP3WGF3I5ANCNFSM56OKIMCA . You are receiving this because you were mentioned.Message ID: @.***>

-- Regards, Anthony LAI Founder & Security Researcher Valkyrie-X Security Research Group "Offensive . Creative . Fun"

 __  _
  .-.'  `; `-._  __  _
 (_,         .-:'  `; `-._

,'o"( (, ) (,-' ,'o"( )> ( (,-' ) -'._.--._( ) ||| |||-'..--._.-' ||| |||

0xdarkfloyd avatar Nov 06 '22 17:11 0xdarkfloyd

This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 15 days.

github-actions[bot] avatar Jan 06 '23 05:01 github-actions[bot]

This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 15 days.

github-actions[bot] avatar Apr 08 '23 05:04 github-actions[bot]