Shellcraft 1 0 8

broken image


After Spain ceded the Philippines to the United States, American forces came to Jolo and ended the 23 years of Spanish military occupation (1876 to 1899). On August 20, Sultan Jamalul Kiram II and Brig. Bates signed the Bates Agreement that continued the gradual emasculation of the Sultanate started by Spain (Treaty of 1878) until March 1915 when the Sultan abdicated his temporal. Shell Shockers is a multiplayer.io FPS game featuring eggs armed with guns. You control one of these weapon-wielding eggs in one of three online game modes where the aim is to shatter your opponents with bullets and bombs. It's the ultimate online egg shooting game! A Modpack about exploration and adventure. 38 Downloads Last Updated: Apr 29, 2021 Game Version: 1.16.5. To fix this, we really just need to shift the stack by 8 bytes through calling any other function before the win function: offset; anyfunctionaddr; winaddr; For example, a payload of payload = 'a'.(0x40+8)+p64(0x4005de)+p64(winaddr) also works where 0x4005de is a simple ret gadget.

  1. Shellcraft 1 0 8 Loi 404
  2. 1 Equals 0
  3. 1 Divided By 0
  4. Shellcraft 1 0 800
  5. Shellcraft 1 0 8 Hp
Shellcraft 1 0 800

Problem

Open the Crafting Menu. First, open your crafting table so that you have the 3x3 crafting grid that looks like this: 2. Add Items to make a Map. In the crafting menu, you should see a crafting area that is made up of a 3x3 crafting grid. To make a map, place 8 papers and 1 compass on Java Edition (PC/Mac), Xbox and PS in the 3x3 crafting grid.

This program executes any shellcode that you give it. Can you spawn a shell and use that to read the flag.txt? You can find the program in /problems/handy-shellcode_4_037bd47611d842b565cfa1f378bfd8d9 on the shell server. Source.

Solution

The solution is basically the same as the shellcode challenge from last year (click the link for my writeup on that).

Here's the exploit script that I used:

flag: picoCTF{h4ndY_d4ndY_sh311c0d3_55c521fe}

Shellcraft 1 0 8 Loi 404

Problem

You're going to need to know how to run programs if you're going to get out of here. Navigate to /problems/practice-run-1_0_62b61488e896645ebff9b6c97d0e775e on the shell server and run this program to receive a flag.

Solution

flag: picoCTF{g3t_r3adY_2_r3v3r53}

Problem

This should be easy. Overflow the correct buffer in this program and get a flag. Its also found in /problems/overflow-0_1_54d12127b2833f7eab9758b43e88d3b7 on the shell server. Source.

Solution

Same as buffer-overflow-0 from last year.

Exploit script:

flag: picoCTF{3asY_P3a5yb197d4e2}

Problem

You beat the first overflow challenge. Now overflow the buffer and change the return address to the flag function in this program? You can find it in /problems/overflow-1_2_305519bf80dcdebd46c8950854760999 on the shell server. Source.

Solution

Same as buffer-overflow-1 from last year.

One thing to clarify is how I found the offset of the return address. In the case, I found the offset to be 0x48+4 or 76. This is obtained by using a tool like radare2 and looking at the stack layout of the function:

As you can see, the buffer is located at ebp-0x48 and we know there are another 4 bytes for the saved ebp register. That's how we can find the offset.

Another approach would be to use something like this and deduce the offset by looking at the segfault address.

Exploit script:

flag: picoCTF{n0w_w3r3_ChaNg1ng_r3tURn5a32b9368}

Problem

You beat the first overflow challenge. Now overflow the buffer and change the return address to the flag function in this program? You can find it in /problems/overflow-1_2_305519bf80dcdebd46c8950854760999 on the shell server. Source.

Solution

This is a simple buffer overflow challenge like OverFlow 1 (read this to see how I found the return address offset), but instead of 32 bit, it is now 64 bit.

There's a slight problem with calling the win function directly because of buffering problems, so we need to call the main first before calling the win function. Our payload would look something like this:

  • offset
  • main_addr
  • win_addr

2019.10.13 Update

The problem with calling the win function directly is not because of buffering issues. Instead, it is triggered by a stack misalignment. When we send a payload without calling the main function:

  • offset
  • win_addr

We see in gdb (with gef) that it crashed on movaps:

A quick google search shows that 'When the source or destination operand is a memory operand, the operand must be aligned on a 16-byte boundary or a general-protection exception (#GP) is generated' which is what caused the segfault. In other words, the program crashed because rsp+0x50 which equals 0x7ffda0c16578 is not a multiple of 16. To fix this, we really just need to shift the stack by 8 bytes through calling any other function before the win function:

  • offset
  • any_function_addr
  • win_addr

For example, a payload of payload = 'a'*(0x40+8)+p64(0x00000000004005de)+p64(win_addr) also works where 0x00000000004005de is a simple ret gadget:

Thanks unprovoked for bringing this to my attention.

Exploit script:

flag: picoCTF{th4t_w4snt_t00_d1ff3r3nt_r1ghT?_1a8eb93a}

Problem

This program is a little bit more tricky. Can you spawn a shell and use that to read the flag.txt? You can find the program in /problems/slippery-shellcode_1_69e5bb04445e336005697361e4c2deb0 on the shell server. Source.

Solution

This is similar to handy-shellcode but a random offset is added to the address that it is calling:

To bypass this, we can add a nop slide in front of our shellcode payload which is basically a ton of nop instructions. This allows the shellcode to execute as long as the calling address lands on one of the nop instructions.

Also, check out the gps challenge from last year which is about the same technique.

Exploit script:

flag: picoCTF{sl1pp3ry_sh311c0d3_0fb0e7da}

Problem

Okay now lets try mainpulating arguments. program. You can find it in /problems/newoverflow-2_2_1428488532921ee33e0ceb92267e30a7 on the shell server. Source.

Solution

Think the challenge author forgot to remove the flag function which makes the challenge solvable with the same script as NewOverFlow-1

Exploit script: Soundsource 4 2 14.

flag: picoCTF{r0p_1t_d0nT_st0p_1t_64362a2b}

Problem

Now try overwriting arguments. Can you get the flag from this program? You can find it in /problems/overflow-2_6_97cea5256ff7afcd9c8ede43d264f46e on the shell server. Source.

Solution

This challenge is about the 32bit x86 calling convention where we need to call the flag function with two parameters. I have already done a detailed writeup for last year's buffer-overflow-2 challenge which is similar.

Exploit script:

flag: picoCTF{arg5_and_r3turn55897b905}

Problem

This time we added a canary to detect buffer overflows. Can you still find a way to retrieve the flag from this program located in /problems/canary_4_221260def5087dde9326fb0649b434a7. Source.

Solution

Same as buffer-overflow-3 from last year. The key point is that we can guess the constant canary one byte at a time and we can also bypass PIE by bruting forcing plus a partial overwrite.

Exploit script:

flag: picoCTF{cAnAr135_mU5t_b3_r4nd0m!_bf34cd22}

Problem

Can you jump your way to win in the following program and get the flag? You can find the program in /problems/leap-frog_1_2944cde4843abb6dfd6afa31b00c703c on the shell server? Source.

Solution

This is a classic ROP challenge. But instead of going through all the hoops as intended, we can set all win* variables to 1 by calling gets with a payload that looks like this:

  • padding
  • gets_plt <- first function to call
  • flag_addr <- second function to call
  • win_addr <- the buffer parameter being passed to gets

Exploit script:

flag: picoCTF{h0p_r0p_t0p_y0uR_w4y_t0_v1ct0rY_f60266f9}

Problem

Can you take advantage of misused malloc calls to leak the secret through this service and get the flag? Connect with nc 2019shell1.picoctf.com 12286. Source.

Solution

Because the program uses malloc instead of calloc, we can allocate a heap chunk for the username that has the same size as a user struct, and then we can free the chunk and allocate the same chunk now as a user struct. Because the data we previously entered is still there, we can set the access_code and get the flag.

Exploit script:

flag: picoCTF{g0ttA_cl3aR_y0uR_m4110c3d_m3m0rY_8aa9bc45}

Problem

Use a format string to pwn this program and get a flag. Its also found in /problems/stringzz_2_a90e0d8339487632cecbad2e459c71c4 on the shell server. Source.

Solution

As suggested by the description, this is a format string attack challenge where we are able to control the format string being passed to printf:

Another important information is that although the flag is loaded onto the heap, there's still a pointer to it located on the stack:

So if we do %XX$s with the correct offset, we can print out the flag.

Exploit script:

Equals

Problem

Open the Crafting Menu. First, open your crafting table so that you have the 3x3 crafting grid that looks like this: 2. Add Items to make a Map. In the crafting menu, you should see a crafting area that is made up of a 3x3 crafting grid. To make a map, place 8 papers and 1 compass on Java Edition (PC/Mac), Xbox and PS in the 3x3 crafting grid.

This program executes any shellcode that you give it. Can you spawn a shell and use that to read the flag.txt? You can find the program in /problems/handy-shellcode_4_037bd47611d842b565cfa1f378bfd8d9 on the shell server. Source.

Solution

The solution is basically the same as the shellcode challenge from last year (click the link for my writeup on that).

Here's the exploit script that I used:

flag: picoCTF{h4ndY_d4ndY_sh311c0d3_55c521fe}

Shellcraft 1 0 8 Loi 404

Problem

You're going to need to know how to run programs if you're going to get out of here. Navigate to /problems/practice-run-1_0_62b61488e896645ebff9b6c97d0e775e on the shell server and run this program to receive a flag.

Solution

flag: picoCTF{g3t_r3adY_2_r3v3r53}

Problem

This should be easy. Overflow the correct buffer in this program and get a flag. Its also found in /problems/overflow-0_1_54d12127b2833f7eab9758b43e88d3b7 on the shell server. Source.

Solution

Same as buffer-overflow-0 from last year.

Exploit script:

flag: picoCTF{3asY_P3a5yb197d4e2}

Problem

You beat the first overflow challenge. Now overflow the buffer and change the return address to the flag function in this program? You can find it in /problems/overflow-1_2_305519bf80dcdebd46c8950854760999 on the shell server. Source.

Solution

Same as buffer-overflow-1 from last year.

One thing to clarify is how I found the offset of the return address. In the case, I found the offset to be 0x48+4 or 76. This is obtained by using a tool like radare2 and looking at the stack layout of the function:

As you can see, the buffer is located at ebp-0x48 and we know there are another 4 bytes for the saved ebp register. That's how we can find the offset.

Another approach would be to use something like this and deduce the offset by looking at the segfault address.

Exploit script:

flag: picoCTF{n0w_w3r3_ChaNg1ng_r3tURn5a32b9368}

Problem

You beat the first overflow challenge. Now overflow the buffer and change the return address to the flag function in this program? You can find it in /problems/overflow-1_2_305519bf80dcdebd46c8950854760999 on the shell server. Source.

Solution

This is a simple buffer overflow challenge like OverFlow 1 (read this to see how I found the return address offset), but instead of 32 bit, it is now 64 bit.

There's a slight problem with calling the win function directly because of buffering problems, so we need to call the main first before calling the win function. Our payload would look something like this:

  • offset
  • main_addr
  • win_addr

2019.10.13 Update

The problem with calling the win function directly is not because of buffering issues. Instead, it is triggered by a stack misalignment. When we send a payload without calling the main function:

  • offset
  • win_addr

We see in gdb (with gef) that it crashed on movaps:

A quick google search shows that 'When the source or destination operand is a memory operand, the operand must be aligned on a 16-byte boundary or a general-protection exception (#GP) is generated' which is what caused the segfault. In other words, the program crashed because rsp+0x50 which equals 0x7ffda0c16578 is not a multiple of 16. To fix this, we really just need to shift the stack by 8 bytes through calling any other function before the win function:

  • offset
  • any_function_addr
  • win_addr

For example, a payload of payload = 'a'*(0x40+8)+p64(0x00000000004005de)+p64(win_addr) also works where 0x00000000004005de is a simple ret gadget:

Thanks unprovoked for bringing this to my attention.

Exploit script:

flag: picoCTF{th4t_w4snt_t00_d1ff3r3nt_r1ghT?_1a8eb93a}

Problem

This program is a little bit more tricky. Can you spawn a shell and use that to read the flag.txt? You can find the program in /problems/slippery-shellcode_1_69e5bb04445e336005697361e4c2deb0 on the shell server. Source.

Solution

This is similar to handy-shellcode but a random offset is added to the address that it is calling:

To bypass this, we can add a nop slide in front of our shellcode payload which is basically a ton of nop instructions. This allows the shellcode to execute as long as the calling address lands on one of the nop instructions.

Also, check out the gps challenge from last year which is about the same technique.

Exploit script:

flag: picoCTF{sl1pp3ry_sh311c0d3_0fb0e7da}

Problem

Okay now lets try mainpulating arguments. program. You can find it in /problems/newoverflow-2_2_1428488532921ee33e0ceb92267e30a7 on the shell server. Source.

Solution

Think the challenge author forgot to remove the flag function which makes the challenge solvable with the same script as NewOverFlow-1

Exploit script: Soundsource 4 2 14.

flag: picoCTF{r0p_1t_d0nT_st0p_1t_64362a2b}

Problem

Now try overwriting arguments. Can you get the flag from this program? You can find it in /problems/overflow-2_6_97cea5256ff7afcd9c8ede43d264f46e on the shell server. Source.

Solution

This challenge is about the 32bit x86 calling convention where we need to call the flag function with two parameters. I have already done a detailed writeup for last year's buffer-overflow-2 challenge which is similar.

Exploit script:

flag: picoCTF{arg5_and_r3turn55897b905}

Problem

This time we added a canary to detect buffer overflows. Can you still find a way to retrieve the flag from this program located in /problems/canary_4_221260def5087dde9326fb0649b434a7. Source.

Solution

Same as buffer-overflow-3 from last year. The key point is that we can guess the constant canary one byte at a time and we can also bypass PIE by bruting forcing plus a partial overwrite.

Exploit script:

flag: picoCTF{cAnAr135_mU5t_b3_r4nd0m!_bf34cd22}

Problem

Can you jump your way to win in the following program and get the flag? You can find the program in /problems/leap-frog_1_2944cde4843abb6dfd6afa31b00c703c on the shell server? Source.

Solution

This is a classic ROP challenge. But instead of going through all the hoops as intended, we can set all win* variables to 1 by calling gets with a payload that looks like this:

  • padding
  • gets_plt <- first function to call
  • flag_addr <- second function to call
  • win_addr <- the buffer parameter being passed to gets

Exploit script:

flag: picoCTF{h0p_r0p_t0p_y0uR_w4y_t0_v1ct0rY_f60266f9}

Problem

Can you take advantage of misused malloc calls to leak the secret through this service and get the flag? Connect with nc 2019shell1.picoctf.com 12286. Source.

Solution

Because the program uses malloc instead of calloc, we can allocate a heap chunk for the username that has the same size as a user struct, and then we can free the chunk and allocate the same chunk now as a user struct. Because the data we previously entered is still there, we can set the access_code and get the flag.

Exploit script:

flag: picoCTF{g0ttA_cl3aR_y0uR_m4110c3d_m3m0rY_8aa9bc45}

Problem

Use a format string to pwn this program and get a flag. Its also found in /problems/stringzz_2_a90e0d8339487632cecbad2e459c71c4 on the shell server. Source.

Solution

As suggested by the description, this is a format string attack challenge where we are able to control the format string being passed to printf:

Another important information is that although the flag is loaded onto the heap, there's still a pointer to it located on the stack:

So if we do %XX$s with the correct offset, we can print out the flag.

Exploit script:

flag: picoCTF{str1nG_CH3353_166b95b4}

Problem

You can only change one address, here is the problem: program. It is also found in /problems/got_1_6a9949d39d119bd2973bdc661d78f71d on the shell server. Source.

Solution

This is a simple GOT overwrite challenge. It is the same as got-shell? from last year.

Exploit script:

flag: picoCTF{A_s0ng_0f_1C3_and_f1r3_e122890e}

Problem

Exploit the function pointers in this program. It is also found in /problems/pointy_1_e2b49b679521bd6d957b864c91e7b39e on the shell server. Source.

Solution

The bug in the program is that we can select professors as students and students as professors. By writing the lastScore of a professor and then treating it as a student, we can control the scoreProfessor field and retrieve the flag.

Exploit script:

flag: picoCTF{g1v1ng_d1R3Ct10n5_16d57b6c}

Problem

The most revolutionary game is finally available: seed sPRiNG is open right now! seed_spring. Connect to it with nc 2019shell1.picoctf.com 4160.

Solution

By reversing the program, we can see that our objective is to correctly guess 30 random numbers in a row:

We can accomplish this if we are able to determine the exact value time(0) returns which is the seed. This can be done in python as described here.

Exploit script:

flag: picoCTF{pseudo_random_number_generator_not_so_random_24ce919be49576c7df453a4a3e6fbd40}

Problem

Just pwn this program and get a flag. It's also found in /problems/afterlife_6_1c6bc56bd64007e5162e284db4d03df5 on the shell server. Source.

Solution

This is a heap overflow attack where we have a leaked heap address. A quick check with radare2 reveals that it is not using the standard malloc in libc:

The first attack that came to mind is the unlink attack. We can overwrite the fd_ptr and bk_ptr pointers of a freed chunk, so when the chunk is then malloced, fd_ptr+12 = bk_ptr and bk_ptr+8 = fd_ptr. We can utilize this to overwrite the GOT table and get code execution with something like this:

  • exit_got-12 <– fd_ptr
  • leak+8 <– bk_ptr / location of our shellcode.

After unlink, exit_got-12+12 will equal leak+8 the location where we placed our shellcode.

One thing to keep in mind is that 4 bytes of our shellcode would also get corrupted by the unlink, so we need to have a relative jump at the start of our shellcode:

Exploit script:

flag: picoCTF{what5_Aft3r_d2d97c7b}

Problem

Just pwn this program and get a flag. Its also found in /problems/l1im1tl355_1_688adedb3c25bf76cbb2c2a0fe7e9ac3 on the shell server. Source.

Solution

Because there's no bound check in c arrays, we can enter negative numbers for the index. This allows us to overwrite the return address of the replaceIntegerInArrayAtIndex function since the stack looks something like this:

  • lower stack address
  • replaceIntegerInArrayAtIndex: stack data
  • replaceIntegerInArrayAtIndex: saved ebp
  • replaceIntegerInArrayAtIndex: return address (-5)
  • main: other stack data
  • main: array (+0)
  • higher stack address

Exploit script:

flag: picoCTF{str1nG_CH3353_59c3cf5a}

Problem

Just pwn this program using a double free and get a flag. It's also found in /problems/secondlife_2_ecf87473c7934afc6ea15edd2ee954ca on the shell server. Source.

Solution

This is a double-free heap exploit challenge. The unlink solution that I wrote for AfterLife works for this challenge as well, so I just copied the same script over with minor changes.

Exploit script:

flag: picoCTF{HeapHeapFlag_d11a9aaf}

Problem

1 Equals 0

Can you exploit the following program to get a flag? You can find the program in /problems/rop32_3_f3a10b5fa410146f5328fb7b3e63e7c0 on the shell server. Source.

Solution

Based on the challenge name and the fact that the binary is statically compiled, we can tell that this is a pure ROP challenge where we need to get code execution:

The hard way to approach this type of problems is to do it manually, but I prefer to do it with an automated tool which is the easy way out:

Running the command above produces an exploit payload that you can just copy and paste into your script.

Exploit script:

flag: picoCTF{rOp_t0_b1n_sH_cb4c373e}

Problem

Time for the classic ROP in 64-bit. Can you exploit this program to get a flag? You can find the program in /problems/rop64_5_7608f52be26a84e5625c50ba7adb22e0 on the shell server. Source.

Solution

Same approach as rop32.

Exploit script:

flag: picoCTF{rOp_t0_b1n_sH_w1tH_n3w_g4dg3t5_cfc72366}

Problem

Just pwn this using a heap overflow taking advantage of douglas malloc free program and get a flag. Its also found in /problems/heap-overflow_5_39d709fdc06b81d3c23b73bb9cca6bdb on the shell server. Source.

1 Divided By 0

Solution

Another challenge that is solved with the unlink method just like Afterlife and Secondlife. The difference is that this time we need a bit more finessing. Photozoom pro version 6 0 2 download free.

To make sure we trigger the unlink mechanics, we need to do two things: 1. change the size of the lastname chunk so it would be treated as a smallbin instead of a fastbin 2. fake a freed chunk after lastname that would be unlinked when merged with the lastname chunk.

The stack layout would look something like this:

  • fullname <– contains our shellcode
  • name <– untouched
  • lastname <– now with a size of 0x100 so it would be treated as a smallbin
  • a fake free chunk added that have the fd_ptr and bf_ptr set

When lastname is freed, it will try to merge with neighboring chunks which would trigger the unlink.

Exploit script:

flag: picoCTF{a_s1mpl3_h3ap_69424381}

Most importantly, pwntools provides GDB integration, which is extremely useful.

Let's follow an example using the vulnerable binary from the Lab 04 - Exploiting. Shellcodes tutorial.

Shellcraft 1 0 800

Notice the gdb.attach(p) and raw_input lines. The former will open a new terminal window with GDB already attached. All of your GDB configurations will be used, so this works with PEDA as well. Let's set a breakpoint at the ret instruction from the main function:

The continue command will return control to the terminal in which we're running the pwntools script. This is where the raw_input comes in handy, because it will wait for you to say 'go' before proceeding further. Now if you hit at the Send payload? prompt, you will notice that GDB has reached the breakpoint you've previously set.

Shellcraft 1 0 8 Hp

You can now single-step each instruction of the shellcode inside GDB to see that everything is working properly. Once you reach int 0x80, you can continue again (or close GDB altogether) and interact with the newly spawned shell in the pwntools session.





broken image