문제에서 chall.pcap 파일 한 개가 주어졌습니다. 해당 pcap 파일 내에는 BLE (블루투스) 통신 패킷이 존재하였으며, binwalk으로 확인하면 여러 PNG image 데이터가 같이 존재하는 것을 확인할 수 있습니다.
해당 PNG 파일을 추출하는 방향으로 문제 풀이 방법을 설정하였습니다.
취약점은 아니고, 블루투스 통신 패킷을 처음보는거라 시간이 조금 걸렸지만, L2CAP 프로토콜 통신을 통해 PNG 파일이 통신되는 것을 확인할 수 있었습니다. SDU 패킷은 Start SDU, Continuation SDU, End SDU로 나뉘어져 통신이 진행되고 있었습니다.
해당 패킷을 모두 추출하여 이어붙이는 형태로 PNG 파일을 복원하는 것을 목표로 진행을 하였습니다. 해당 과정에서 Header, Control, FCS 등 통신 패킷에는 존재하지만 PNG 파일에는 들어가지 않는 데이터들을 삭제하는 과정을 거쳤습니다. 다만, Start-Continuation-End 과정이 1번이 아닌 여러번 반복되었고, End 이후 새로운 Start 이후에 몇 bytes를 삭제해야되는지를 알 수가 없었습니다. 처음 접근 방식으로 2번 째 과정 패킷을 1bytes 씩 삭제하며 붙이는 스크립트를 작성했었는데, 이론적으로는 가능해야하는데 FLAG를 획득하지 못했습니다(스크립트를 잘못 작성했을 수도 있습니다) 이후에 PNG-Fixer(https://github.com/Pourliver/PNG-Fixer)라는 툴을 사용하여 PNG 값 내 잘못된 데이터를 식별하고 hxd로 해당 데이터의 위치를 검색해서 bytes를 삭제하여 IDAT가 정확한 위치에 가도록 조정하였습니다.
위 과정을 통해 Start SDU 과정에서 6bytes를 추가적으로 삭제하면 PNG 파일을 획득할 수 있는 것을 확인하였습니다.
코드 내 bin 파일은 wireshark에서 SDU 통신 패킷을 하나씩 모두 저장한 것입니다. (단축키 Ctrl+Shift+x)
def concat(file_name):
f1 = open("./out.png", 'rb')
f2 = open(file_name, 'rb')
tmp = f1.read() + f2.read()
f3 = open("./out"+file_name+".png", 'wb')
f3.write(bytes(tmp))
f4 = open("./out.png", 'wb')
f4.write(bytes(tmp))
f4.close()
f3.close()
f1.close()
f2.close()
def delete_bytes(num, file_name):
f1 = open(file_name, 'rb')
data = f1.read()
f1.close()
data = data[num:]
#print(data)
f2 = open(file_name, "wb")
f2.write(bytes(data))
f2.close()
def delete_last_bytes(file_name):
f1 = open('../p2-original/'+file_name, 'rb')
data = f1.read()
f1.close()
data = data[:-2]
f2 = open(file_name, "wb")
f2.write(bytes(data))
f2.close()
ary = ['00-s.bin', '01-c.bin', '02-c.bin', '03-c.bin', '04-c.bin', '05-c.bin', '06-c.bin', '07-c.bin', '08-e.bin', '09-s.bin', '10-c.bin', '11-c.bin', '12-c.bin', '13-c.bin', '14-c.bin', '15-c.bin', '16-c.bin', '17-e.bin', '18-s.bin', '19-c.bin', '20-c.bin', '21-c.bin', '22-c.bin', '23-c.bin', '24-c.bin', '25-c.bin', '26-e.bin', '27-s.bin', '28-e.bin']
#ary = ['00-02.bin', '01-04.bin', '02-06.bin', '03-08.bin', '04-0a.bin', '05-0c.bin', '06-0e.bin', '07-10.bin', '10-16.bin', '11-18.bin', '12-1a.bin', '13-1c.bin', '14-1e.bin', '15-20.bin', '16-22.bin', '17-24.bin', '18-26.bin', '19-28.bin', '20-2a.bin', '21-2c.bin', '22-2e.bin', '23-30.bin', '24-32.bin', '25-34.bin', '26-36.bin', '27-38.bin', '28-3a.bin', '29-3c.bin']
for item in ary:
delete_last_bytes(item)
for item in ary:
if 's' in item:
delete_bytes(13, item)
else:
delete_bytes(11, item)
f = open("./out.png", "w")
f.close()
for item in ary:
if 's' in item:
delete_bytes(6, item)
concat(item)
f = open("./out.png", "rb")
data = f.read()
data = data[33:]
f.close()
f = open("./flag.png", "wb")
f.write(bytes(data))
f.close()