HTB academy intro to assembly language skills assessment task 1

I’ve been pulling my hair out for 3 days trying to figure this out.

I have successfully added the loop and xor decoded the code on the stack, but I have no idea how to run it once it’s there. I have tried everything from writing a “print” syscall to copy and pasting the code and just using pwntools to run it. Nothing works. I cant get the shell code to excecute. Please help

This is my code:

global _start
section .text
_start:
mov rax,0xa284ee5c7cde4bd7
push rax
mov rax,0x935add110510849a
push rax
mov rax,0x10b29a9dab697500
push rax
mov rax,0x200ce3eb0d96459a
push rax
mov rax,0xe64c30e305108462
push rax
mov rax,0x69cd355c7c3e0c51
push rax
mov rax,0x65659a2584a185d6
push rax
mov rax,0x69ff00506c6c5000
push rax
mov rax,0x3127e434aa505681
push rax
mov rax,0x6af2a5571e69ff48
push rax
mov rax,0x6d179aaff20709e6
push rax
mov rax,0x9ae3f152315bf1c9
push rax
mov rax,0x373ab4bb0900179a
push rax
mov rax,0x69751244059aa2a3
push rax
mov rbx,0x2144d2144d2144d2
mov rcx, 14
lea rdx, [rsp]
loopfun:
xor [rdx], rbx
add rdx, 8
loop loopfun

2 Likes

Like a Neanderthal, I dumped the memory in question in the debugger, copy/pasted it into a text editor, and manually cleaned it up. (I’m sure more patient/efficient people wrote the asm commands to print it out though :blush: ). After that I did use a script presented earlier in the module to run it.

1 Like

Type your comment> @PartyGolbez said:

Like a Neanderthal, I dumped the memory in question in the debugger, copy/pasted it into a text editor, and manually cleaned it up. (I’m sure more patient/efficient people wrote the asm commands to print it out though :blush: ). After that I did use a script presented earlier in the module to run it.

I tried that too after a while and It didn’t work. Did you have to reverse the byte order (because it’s little endian)? Did you put it in backwards (because by the end rsp is the last set of instructions given) ?

Good question about the little-endianness. I did not reverse the order and I dumped “giant” (8-byte) words. However I just tried dumping smaller units and yeah, they are reversed to some extent. I need to wrap my head around why the giant size is the only view that dumps the memory exactly “in order” - it’s definitely confusing.

As far as the range of memory (the above notwithstanding), write it out from the lower address to the higher address, just as a CPU would read it. (don’t get confused by the way the stack grows “down”).

I wonder if there’s a way to run this straight from memory (or if that’s what’s intended) vs dumping it out and running it later. I’m definitely not a magician when it comes to this :slight_smile:

Type your comment> @PartyGolbez said:

Good question about the little-endianness. I did not reverse the order and I dumped “giant” (8-byte) words. However I just tried dumping smaller units and yeah, they are reversed to some extent. I need to wrap my head around why the giant size is the only view that dumps the memory exactly “in order” - it’s definitely confusing.

As far as the range of memory (the above notwithstanding), write it out from the lower address to the higher address, just as a CPU would read it. (don’t get confused by the way the stack grows “down”).

I wonder if there’s a way to run this straight from memory (or if that’s what’s intended) vs dumping it out and running it later. I’m definitely not a magician when it comes to this :slight_smile:

Finally got it. Thank you!

That’s awesome you got it, congrats! I am compelled to correct something I said though. I implied that dumping “giant” words in gdb shows the actual order of the bytes in memory. This is incorrect - the way to show the true order of the bytes in memory is to dump them one byte at a time (x/16xb [address]) for example. Dumping larger sizes (e.g. halfwords, etc) causes the debugger to “interpret” them as that size and reverse the bytes within the individual units . So dumping giant words (x/2xg [address]) shows each set of 8 bytes in reverse order.

So how did me copying and pasting these giant words into a text editor produce a valid result? I honestly have no idea. Maybe the lab was set up that way, assuming we’d be looking at the values in 64-bit (aka 8-byte aka giant-word aka register-sized) chunks. But I would love someone to explain that to me.

Sorry if I’ve confused everyone :slight_smile: Would love a True Expert to weigh in!

Type your comment> @PartyGolbez said:

That’s awesome you got it, congrats! I am compelled to correct something I said though. I implied that dumping “giant” words in gdb shows the actual order of the bytes in memory. This is incorrect - the way to show the true order of the bytes in memory is to dump them one byte at a time (x/16xb [address]) for example. Dumping larger sizes (e.g. halfwords, etc) causes the debugger to “interpret” them as that size and reverse the bytes within the individual units . So dumping giant words (x/2xg [address]) shows each set of 8 bytes in reverse order.

So how did me copying and pasting these giant words into a text editor produce a valid result? I honestly have no idea. Maybe the lab was set up that way, assuming we’d be looking at the values in 64-bit (aka 8-byte aka giant-word aka register-sized) chunks. But I would love someone to explain that to me.

Sorry if I’ve confused everyone :slight_smile: Would love a True Expert to weigh in!

There must be a way to iterate through the stack and print the result as shell code

Definitely, after xor-ing you could probably write a similar loop and use printf (covered in the “functions” part of the module) to format the memory as hex and print it out.

Hey there, I get the shell code after adding the loop to xor the rdx register and then look at its content with x/2x $rdx (which should show it with the correct endianess, as opposed to, for example, looking at registers in gef). I then do a bit of text manipulation… reverse the word order, remove the 0x from the start of each string/byte, join the result in a long hex which I use for pwntools run_shellcode. But what I get is and empty line. I try to input various commands (ls, whoami) expecting it to be a shell but it dies and it goes back to the python prompt. Am I doing something wrong in principle?

Can you help me with task one I cant find the flag I try to find vaules and put in the text file
example
x/2xg _start+10
and after that I edit it and run with
python3 loader.py ‘xex exitet’
and I dont get hte flag
can you tell me what i’m doing wrong?

this mean we can use objdump dumped the memory , cut 0x and combine all hex.
after that use pwn disasm am I right?

Finaly how can you reslove it. Can you show me detail, i stuck it 2 weks. Thanks! @XSSDoctor

So I ran the shell code and got something back, but it’s not the right answer, even though it looks like the right answer given the ‘format’. Can someone who figured this out PM me so I can confirm if I’ve got the right output? If not can you tell me how to get the right output?

I finally solved! and after reading the forum posts, some of them may lead to confusion.

  • You don’t need to do any transformation to the result of the register, it is the value that has to be.
  • It is not necessary to use any function to write the values on the screen, in fact, the printf function can lead you to confusion with its results.
  • Debug, and debug again, what is the value of the rdx register before the xor? and after? is there something wrong with any of the values?

I hey I just found the flag myself. I did manage to utilize the printf function after the fact, but there’s an issue around the 10th iteration. Mind taking a look at it?

Thank you very much, you have helped me to find the flag. I have followed the following steps:

1). I have used the code provided by @XSSDoctor and generated the binary.

2). I have opened the binary with “gdb” and made a breakpoint after the “xor”. The idea is to get the value of the “rdx” register in each of the 14 iterations. The ShellCode is the concatenation of the 14 iterations.

3). You run the ShellCode.

I ended up very tired after this

Initially I did it a bit different:

mov rcx, 14
mov rdx, rsp
loopStack:
mov rdi, [rdx]
xor rdi, rbx
add rdx, 8
loop loopStack

but it did not work. I see some kind of new shell, but typing any letter throws an error.
Then I tried what @XSSDoctor suggested and it gave me the same HEX line (‘4831…0f05’), so it’s still does not work. Could anyone please help? Maybe there’s something special in how you feed this line to ‘loader.py’?

Finally I did it. @mezzown was right.
Whoever stuck with this task, read @mezzown comment attentively and revise ‘shellcode requirements’ once again.

I still do not understand how it works, could you explain it more? I have no idea what I should add what in my modified code. Thanks a lot

What I did is after each change happen in rdx i coppied it and combine them and then used loader.py and put the hex values combined without the 0x and it worked.