make diffrent template on last six post published

As written, you are checking the total post count against your counter. That is, $wp_query is the total post count for the query not the per page count.

Now, assume 30 posts total in the query with 10 posts per page. Your counter starts and will get all the way to 10, but $ctr < $wp_query->found_posts - $last_no_of_posts is always true. $ctr will be 10 at the end of that loop but $wp_query->found_posts - $last_no_of_posts will be 30 – 10, or 20. The same with the second page of results, because your counter starts over. The same with the page after that. Under that circumstance, and many like it, $ctr is always less than found_posts minus your counter. The only way this identifies the last six is if all results are on one page– no pagination. Perhaps that is what you are doing, and that is what you want.

However, if you need to identify the last six on each page of pagination you need to rewrite it to use post_count not found_posts:

while ( have_posts() ) { the_post(); 

   if ($ctr < $wp_query->post_count - $last_no_of_posts) {
      // require special template
      get_template_part( 'loop', 'special' );
   } else {
      // regular template
      get_template_part( 'loop', 'index' );
   }
   $ctr++;

}

If you want the last six on the very last page of pagination you need (untested):

if ($wp_query->current_post >= $wp_query->found_posts - $last_no_of_posts) {