• Bugku MISC做题笔记


    简单套娃DX

    这一题需要对png图片的结构有所了解。详细可参考https://www.w3.org/TR/png/

    幸好每一张图片只有一个错误,逐步调试,就可以发现所有错误,修正即可。具体错误参看python程序中的注释:

    1. import os
    2. src_dir = '.\\XD\\'
    3. des_dir = '.\\out\\'
    4. src_files = os.listdir(src_dir)
    5. des_files = os.listdir(des_dir)
    6. f_count={0:0,1:0,2:0,3:0,4:0,5:0,6:0,7:0}
    7. for fname in src_files:
    8. if fname in des_files:
    9. continue
    10. with open(src_dir+fname,'rb') as f:
    11. srcdata = f.read()
    12. #丢掉了文件头标识
    13. if srcdata[1:4] != b'PNG':
    14. desdata = 0x89504E470D0A1A0A.to_bytes(8,'big') + srcdata
    15. f_count[1] += 1
    16. #IHDR块长度和标识码被清零
    17. elif srcdata[8:0x10] == 0x0000000000000000.to_bytes(8, 'big'):
    18. desdata = srcdata[:8] + 0x0000000D49484452.to_bytes(8,'big') + srcdata[16:]
    19. f_count[2] += 1
    20. #IHDR宽高值不对
    21. elif srcdata[0xc:0x10] == b'IHDR' and srcdata[0x10:0x18] != 0x0000000500000005.to_bytes(8,'big'):
    22. desdata = srcdata[:0x10] +0x5.to_bytes(4,'big') + 0x5.to_bytes(4,'big') + srcdata[0x18:]
    23. f_count[3] += 1
    24. #IDAT块长度被清零
    25. elif srcdata[0x21:0x29] == 0x00000000.to_bytes(4, 'big')+b'IDAT':
    26. if srcdata.index(b'eXIf') >= 0:
    27. IDAT_len = srcdata.index(b'eXIf') - 0x29 - 4 -4
    28. else:
    29. print('[!] Error!! %s'%fname)
    30. break
    31. desdata = srcdata[:0x21] + IDAT_len.to_bytes(4,'big') + srcdata[0x25:]
    32. f_count[4] += 1
    33. #IDAT块标识被删除
    34. elif srcdata[0xc:0x10] == b'IHDR' and srcdata[0x25:0x29] != b'IDAT':
    35. desdata = srcdata[:0x25] + b'IDAT' + srcdata[0x25:]
    36. f_count[5] += 1
    37. #IHDR头的颜色类型错误
    38. elif srcdata[0xC:0x10] == b'IHDR' and srcdata[0x18:0x1A] != 0x0100.to_bytes(2,'big'):
    39. desdata = srcdata[:0x18] + 0x0100.to_bytes(2,'big') + srcdata[0x1A:]
    40. f_count[6] += 1
    41. #IHDR块被放到了倒数第二块,IDAT变为第一块
    42. elif srcdata[0xc:0x10] == b'IDAT':
    43. IHDR_block_begin = srcdata.index(b'IHDR') - 4
    44. IHDR_block = srcdata[IHDR_block_begin:IHDR_block_begin+25]
    45. desdata = srcdata[:8] + IHDR_block + srcdata[8:IHDR_block_begin] + srcdata[IHDR_block_begin+25:]
    46. f_count[7] += 1
    47. else:
    48. desdata = srcdata
    49. f_count[0] += 1
    50. with open(des_dir+fname,'wb') as f:
    51. f.write(desdata)
    52. print(f_count)

    图片修正以后,观察图片内容,应该是二维码碎片。查看每个图片的exif信息,发现数据:

    1. import os
    2. from PIL import Image
    3. basedir = '.\\out\\'
    4. list = []
    5. for fname in os.listdir(basedir):
    6. image = Image.open(basedir+fname)
    7. exif = image.getexif()
    8. list.append([ int(exif[282]),int(exif[283]) ])
    9. image.close()
    10. list.sort(key=lambda x: [x[0], x[1]])
    11. print(list)
    12. #[[0, 0], [0, 1], [0, 2], [0, 3], [0, 4], [0, 5], [0, 6], [0, 7], [0, 8], [0, 9], [0, 10], [0, 11], [0, 12], [0, 13], [0, 14], [0, 15], [0, 16], [0, 17], [0, 18], [0, 19],
    13. #...
    14. # [449, 0], [449, 1], [449, 2], [449, 3], [449, 4], [449, 5], [449, 6], [449, 7], [449, 8], [449, 9], [449, 10], [449, 11], [449, 12], [449, 13], [449, 14], [449, 15], [449, 16], [449, 17], [449, 18], [449, 19]]

    因此这些应该是每个图片的坐标,依据这些坐标进行拼接图片,得到flag:

    1. import os
    2. from PIL import Image
    3. basedir = '.\\out\\'
    4. list = []
    5. newimg = Image.new('RGB',(450*5,20*5),(255,255,255)) #白底
    6. for fname in os.listdir(basedir):
    7. image = Image.open(basedir+fname)
    8. exif = image.getexif()
    9. x,y = int(exif[282])*5,int(exif[283])*5
    10. newimg.paste(image,(x,y,x+5,y+5))
    11. image.close()
    12. newimg.save('new.png')

  • 相关阅读:
    lambda表达式
    Vue3 - 组件通信(子传父)
    Shell编程规范与变量使用
    基于非线性参数的海洋捕食者算法
    python发送邮件和企业微信
    Spring项目-前端问题:Can‘t find variable:$
    Vue3种常用插槽的使用
    c语言每日一练(14)【加强版】
    在 centos7 上安装Docker
    限流组件设计
  • 原文地址:https://blog.csdn.net/lakeside1/article/details/136740162