1、首先进行交互,看看会发生什么,随便输入点东西,会发现接收到一堆东西,猜测应该是密文。
2、对出题人发布的部分题目源码进行代码审计,发现如下问题
(1)根据输入的的字符串不同,会有三条路走,之前随便输入的字符串,走的是第三条路。
还有两条路是:如果输入字符串以“getapikey:”开头,则会对字符串进行加密;如果输入字符串以“getflag:”开头,则会对字符串进行解密,而且如果(parse_profile(data)==1),则会输出flag;
(2)对字符串加密时,会在输入的字符串前后加一些东西,而且输入的字符串中不能有“;”,如下图所示。
(3)加密方式是cbc模式下的des加密,我们不知道初始向量,不知道密钥,那么就自然想到用位反转来破解。
(4)那么我们需要位反转什么呢?再来看一下下面这部分代码。
也就是说,如果在解密出来的明文中含有“;admin=true”,就会发送flag。
(5)那么解题思路就出来了
①首先发送“getapikey:admin=true”,对方会发送一段密文;
②然后对密文进行处理得到新密文,使得再次解密时会解密出“;admin=true”;
要改变“”=>“;”,“”在明文中是第33位,des加解密16个一组,也就“”在第三个分组的第一位,那我们就需要改变密文中第二组的第一个,使之异或解密出“;”。
③最后发送“getflag:新密文”,就会接收到flag;
最终flag为:flag{laokong_skr_flag}。
(6)最后附上脚本
from pwn import *
from LibcSearcher import *
import pwnlib
import socket
import sys
context.log_level='debug'
context.terminal=['gnome-terminal','-x','sh','-c']
s = socket.socket()
host = '172.22.117.52'
port = 20001
s.connect((host,port))
s.recv(1024)
s.send("getapikey:*admin=true")
data = s.recv(1024)
print data
data = s.recv(1024)
print data
print len(data)
#data = data.strip('\n')
data = data.strip()
# print len(data)
# print data
# print len(data)
#print data
data = data.decode("hex")
# print data
# print len(data)
#data = hex(data.decode("hex"))
data = list(data)
# print data
data[16] = chr(ord("*") ^ ord(data[16])^ ord(";"))
data = "".join(data)
data = data.encode("hex")
# print data
# print len(data)
s.send("getflag:" + data)
print s.recv(1024)
print s.recv(1024)
print s.recv(1024)
print s.recv(1024)